web-dev-qa-db-ja.com

QDialog exec()および結果値の取得

QDialogに似た機能を実装するためにQMessageBoxをサブクラス化しました(カスタマイズを可能にするためにこれが必要でした)。テキストメッセージと[OK]、[キャンセル]ボタンがあります。 exec()を使用してブロックするダイアログを表示しています。ここで、ユーザーが[OK]または[キャンセル]をクリックしたときにtrue/falseの値を返すにはどうすればよいですか?

ボタンをsetResult()に接続してみて、クリックすると結果値を返しましたが、

  1. ボタンをクリックしてもダイアログボックスは閉じません。
  2. 戻り値が正しくありません。以下は私が書いたコードです。 exec/resultの部分が間違っていると思いますが、修正方法がわかりません。
_class MyMessageBox : public QDialog {
    Q_OBJECT

private slots:

    void onOKButtonClicked() { this->setResult(QDialog::Accepted); }
    void onCancelButtonClicked() { this->setResult(QDialog::Rejected); }

public:
    MyMessageBox(QMessageBox::Icon icon, const QString& title,
        const QString& text, bool showCancelButton = true,
        QWidget* parent = 0);

    virtual void resizeEvent(QResizeEvent* e);

    QDialog::DialogCode showYourself()
    {
        this->setWindowModality(Qt::ApplicationModal);
        this->exec();
        return static_cast<QDialog::DialogCode>(this->result());
    }
};
_

ユーザーはクラスをインスタンス化し、showYourself()を呼び出します。この関数は値を返し、ダイアログを閉じる(および削除する)ことも期待されています。

部分的なコードを投稿しました。さらに必要な場合はお知らせください。完全版を投稿します。

22
go4sri

いくつかのポイント:

  1. setResult()を自分で使用するのではなく、 QDialog :: accept() および QDialog :: reject() を使用します。
  2. 信号とスロットを十分に活用していないようです。ダイアログの信号を聞くには、ダイアログ(または別のダイアログ)を作成するオブジェクトが必要です。
  3. コードでは、信号をスロットに接続していません。
  4. 私の修正では、onOKButtonClickedonCancelButtonClickedは不要です。
  5. 私の修正では、showYourself()は必要ありません。 execを呼び出すだけで、イベント情報が流れます。

ダイアログを表示する前に、このコードを追加する必要があります(thisはダイアログメソッド内にあると仮定します):

QObject::connect(acceptButton, SIGNAL(clicked()), this, SLOT(accept()));
QObject::connect(rejectButton, SIGNAL(clicked()), this, SLOT(reject()));

呼び出し元オブジェクトには

void someInitFunctionOrConstructor(){
   QObject::connect(mydialog, SIGNAL(finished (int)), this, SLOT(dialogIsFinished(int)));
}

void dialogIsFinished(int){ //this is a slot
   if(result == QDialog::Accepted){
       //do something
       return
   }
   //do another thing
}
26
UmNyobe

別の解決策:

    // set signal and slot for "Buttons"
    connect(YesButton, SIGNAL(clicked()), dlg, SLOT(accept()));
    connect(NoButton, SIGNAL(clicked()), dlg, SLOT(reject()));

    // show modal window event loop and wait for button clicks
    int dialogCode = dlg->exec();

    // act on dialog return code
    if(dialogCode == QDialog::Accepted) { // YesButton clicked }
    if(dialogCode == QDialog::Rejected) { // NoButton clicked }
17
Jens A. Koch

ケース1ボタンをクリックしても、ダイアログボックスは閉じません。

このためには、それぞれのSLOTSでダイアログを閉じる必要があります。

_void onOKButtonClicked(){ this->setResult(QDialog::Accepted); this->close();}
void onCancelButtonClicked(){ this->setResult(QDialog::Rejected);this->close();}  
_

注:標準のQMessageBoxでOkボタンまたは[キャンセル]ボタンをクリックした後のみ、setResult()関数がトリガーされ、ステータスが変更されます。逆の場合も同じ効果が得られます

ケース2戻り値が正しくありません。

ダイアログが閉じられて初めて、result()関数で結果が利用可能になると思います。ケース1で指定された変更を行った後、解決されると思います。

それでも解決しない場合は、独自のプライベートメンバー関数を使用して解決してください。

9
ScarCode