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