QDialog exec() и получение значения результата
Я разделил на подклассы QDialog
для реализации функциональности, аналогичной QMessageBox
(мне нужно было это сделать для настройки). Он имеет текстовое сообщение и ОК, кнопки Отмена. Я показываю диалог, используя exec()
, чтобы заблокировать его. Теперь, как мне вернуть значения true/false, когда пользователь нажимает кнопку OK/Cancel?
Я попытался подключить кнопки к setResult()
, а затем вернуть значение результата при нажатии, но
- Нажатие на кнопки не закрывает диалоговое окно
- возвращаемое значение неверно.
Ниже приведен код, который я написал. Я думаю, что я ошибаюсь в части 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()
, который, как ожидается, вернет значение, а также закроет (и удалит) диалоговое окно.
Я разместил частичный код. Дайте мне знать, если вам нужно больше, и я опубликую полную версию.
Ответы
Ответ 1
Некоторые моменты:
- Вместо использования
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
}
Ответ 2
Другое решение:
// 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 }
Ответ 3
Случай 1. Нажатие на кнопки не закрывает диалоговое окно.
Для этого вам нужно закрыть диалоговое окно на соответствующем SLOTS
, поэтому используйте
void onOKButtonClicked(){ this->setResult(QDialog::Accepted); this->close();}
void onCancelButtonClicked(){ this->setResult(QDialog::Rejected);this->close();}
Примечание. Только после нажатия кнопки "Ok" или "Отмена" в стандартном QMessageBox запускается функция setResult(), и статус изменяется. Это не тот же эффект, когда делается наоборот.
Случай 2 Неверное значение возврата.
Я думаю, что только после закрытия вашего диалога вы получите результат, доступный в функции result()
. Поэтому я думаю, что это будет решено после внесения изменений, указанных в случае 1.
Если он по-прежнему сохраняется, используйте свою собственную функцию-член для его разрешения.