2016-09-22 10 views
0

私のアプリケーションでは、複雑なQWidgetから派生したGUI要素が含まれているQDialogを持っています。 QDialogはモーダルでexec()で開き、組み込みのGUI要素はすべてのユーザー操作を処理します。QWidgetが親を失う

QDialogがこのように行われている、閉じることができたときだけそうこの子-QWidgetのは知っている:QDialogがクローズする必要があり、QWidgetのためだけでなく

QDialog* parent=qobject_cast<QDialog*>(parentWidget()); 
if (parent) parent->close(); 

、これが必要です。

これで、QDialog-> exec()が返されたが、Dialog(またはGUI要素のみ)がまだ表示されていた状況がユーザーから報告されました。ログファイルから、この呼び出しが実行された直後にQDialog-> exec()が実際に返ってきたコードを見ることができます。

私の現在の仮定:GUI要素が親を失っているため、「親」がNULLだったので上記のclose()呼び出しが呼び出されませんでした。

これはどうやって起こりますか? QWidgetの親が消える正規の方法はありますか?

ありがとうございます!

+3

あなただけの) '(受け入れにあなたの子供の信号を接続または' '拒否しない理由は良い理由がありますダイアログの() 'スロット? –

+0

@thugaここではこの問題を再現できないので、このコメントはまったく役に立たないです。 – Elmi

+0

それでは、質問にそれを書いてください。 – thuga

答えて

1

一般に、QDialog::execを使用してイベントループに再入力すると、突然メインスレッドで実行されるすべてのコードが再入可能でなければならないため、問題が発生します。おそらくあなたはそれからの落ち込みに直面しているでしょう。イベントループを再入力しないでください。問題が再現可能になるか、うまくいくでしょう。

ダイアログが受け入れられているか拒否されている場合は、該当するスロットにコードを接続します。私。それに

void do() { 
    MyDialog dialog{this}; 
    auto rc = dialog.exec(); 
    qDebug() << "dialog returned" << rc; 
} 

class Foo : public QWidget { 
    MyDialog dialog{this}; 
    ... 
    Foo() { 
    connect(&dialog, &QDialog::done, this, &Foo::dialogDone); 
    } 
    void do() { 
    dialog.show(); 
    } 
    void dialogDone(int rc) { 
    qDebug() << "dialog returned" << rc; 
    } 
}; 

か、あなたが遅延し、ダイアログ初期化したい場合:

class Foo : public QWidget { 
    MyDialog * m_dialog = nullptr; 
    MyDialog * dialog() { 
    if (! m_dialog) { 
     m_dialog = new MyDialog{this}; 
     connect(m_dialog, &QDialog::done, this, &Foo::dialogDone); 
    } 
    return m_dialog; 
    } 
    ... 
    void do() { 
    dialog()->show(); 
    } 
    void dialogDone(int rc) { 
    qDebug() << "dialog returned" << rc; 
    } 
}; 

をそれをしようとした子ウィジェットの恐ろしいアンチパターンでこれを変更親と仲直りしてください。 ウィジェットが親を持っているという知識は、ウィジェットに漏れてはいけません。親にローカライズされるべきです。したがって、子ウィジェットは、例えば、データは受け入れられました。ダイアログを作成すると、ダイアログのaccept()close()スロットにこの信号を接続します

class MyWidget : public QWidget { 
    Q_OBJECT 
public: 
    Q_SIGNAL void isDone(); 
    ... 
}; 

class MyDialog : public QDialog { 
    QGridLayout layout{this}; 
    MyWidget widget; 
public: 
    MyDialog() { 
    layout.addWidget(&widget, 0, 0); 
    connect(&widget, &MyWidget::isDone, this, &QDialog::accepted); 
    } 
}; 
+0

私はそれが 'QDialog :: exec'のようなネストされたイベントループは可能なら避けなければならないことには言及されていないことに驚いています。それはいくつかのブログで言及されていますが、私はそれがより明らかにすべきだと思います。 – thuga

関連する問題