QDialog exec () и получение результирующего значения


У меня есть подкласс QDialog, чтобы реализовать функциональность, подобную QMessageBox ( мне это нужно было для настройки). На нем есть текстовое сообщение и кнопки OK, отмена. Я показываю диалог, используя exec(), чтобы сделать его блокирующим. Теперь, как я могу вернуть значения true / false, когда пользователь нажимает на OK / Cancel?

Я попытался подключить кнопки к 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 (), который, как ожидается, вернет значение, а также закроет(и удалит) диалоговое окно.

Я опубликовал частичный код. Дайте мне знать, если вам нужно больше, и я опубликую полную версию.

3 20

3 ответа:

Некоторые моменты:

  1. вместо того, чтобы использовать setResult() самостоятельно, используйте QDialog::accept() и QDialog::reject().
  2. похоже, вы не в полной мере пользуетесь сигналами и слотами. Вам нужен объект, который создает диалог (или другой), чтобы слушать сигналы диалога.
  3. в вашем коде вы также не подключаете сигналы к слотам.
  4. С моим исправлением onOKButtonClicked и onCancelButtonClicked не нужны.
  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
}

Другое решение:

    // 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 }

Случай 1 нажатие кнопок не закрывает диалоговое окно.

Для этого вам нужно закрыть диалог на соответствующем SLOTS, поэтому используйте

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

Примечание: только после того, как вы нажмете кнопку Ok или кнопку Cancel в стандартном QMessageBox, функция setResult() активируется и статус изменяется. Это не тот же самый эффект, когда делается наоборот.

Случай 2 возвращаемое значение неверно.

Я думаю, только после того, как ваш диалог закроется, вы получите результат, доступный в функции result(). Таким образом, я предполагаю, что она будет решена после того, как вы внесете изменения, указанные в случае 1.

Если он все еще сохраняется, используйте свою собственную закрытую функцию-член для его разрешения.