[C++] 32 FLTK: 親子ウィジェットを消去するコールバック [移植完了]

前回の続きです。

表示させたモーダルダイアログを消すコールバックを作成しました。最初は汎用ポインタvoid*の扱い方がわかりませんでした。

モーダルダイアログとOKボタンの親子関係を構築させ、ボタンを押すと親子ウィジェット共に消去するといった内容です。解決するまではOKボタンを押すとボタンだけが消えるという怪現象に取りつかれていました。

FLTKの仕様にひたすら振り回されました。当たり前の話ですが、つじつまが合うように書いていけばいずれ解決するという感じです。時間的コスパはとてつもなく悪いですね。

FLTKはあらゆる機能をカバーしていますが、実装するのが本当に大変です。これでQtのような遅さだったらとてもやってられないです。

続けてFl_Multiline_Outputにスクロールバーを付けようとしたところ、ドラッグ&ドロップができなくなったので止めました。スクロールバーがなくてもカーソルを動かせば見えなくなった行を確認できます。

リサイズ時の背景黒化は解決し堅牢性もそれなりの水準に達したので、PNG用アプリとしてPyQt6からの移植を一旦完了とします。

#include "modalDialog.h"
#include <string>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Widget.H>
 
Fl_Button *button;

modalDialog::modalDialog(int w, int h, const char* title, const char* msg)
    : Fl_Window(w, h, title){

    int ws, hs, xs, ys;
    int margin_x = 70;
    int margin_y = 15;

    ws = 60;
    hs = 25;
    xs = w - ws - margin_x;
    ys = h - hs - margin_y;

    // メッセージ
    Fl_Box *g = new Fl_Box(0, 0, w, h-40, msg);
        
    // OKボタン
    button = new Fl_Button(xs, ys, ws, hs, "OK");
    button->parent(this);
    button->callback(PushButtonOK,this);
    button->down_box(FL_UP_BOX);

    resizable(this);
    end();
}

modalDialog::~modalDialog()
{
}

void modalDialog::PushButtonOK(Fl_Widget* widget,void* x)
{
    Fl_Group* window = widget->parent();
    window->hide();
}

背景色黒化対策

img = cv::imread(path,cv::IMREAD_UNCHANGED);

[C++] 31 FLTK:子ウィジェットの座標

[M1 Mac, Big Sur 11.6.5, FLTK 1.3.8, OpenCV 4.5.5]

自製したモーダルダイアログの位置設定に苦労しました。

親ウィンドウを指定したものの相対位置を設定する方法が分からず、仕方ないのでルートを把握しこれに加減して座標を定めました。

ただこの方法では親ウィンドウを動かしても子ウィンドウの位置は変わらずです。あくまでも応急措置になります。

とある大学の研究室がモーダルダイアログ作成のコード例を公開しており、最初はこれを参考にしましたが結局大半は自分で書く形になりました。

難解なC++を使ってコンピュータシミュレーションを研究するというのはさぞかし大変なことでしょう。

2022/4/6追記:
デモアプリの動作を確認したところ、子ウィンドウは親ウィンドウの相対位置を取れていませんでした。もしかしたら出来ない仕様なのかもしれません。
2022/7/28追記:
親ウインドウのルートから子ウィンドウの相対位置を設定できました。以下の記事に記しました。

<該当部分のみ>

dlg = new modalDialog(300, 150, "", "Attention");
        dlg->hotspot(window);
        int x = dlg->x_root();
        int y = dlg->y_root();
        cout<<"x_root "<< x <<" y_root "<< y <<endl;
        dlg->resize(x-10,y+110,300,150);
        dlg->set_modal();
        dlg->show();