8.QT-对话框(模态与非模态)
对话框介绍
- 对话框是于用户进行简易交互的顶层窗口
- QDialog是Qt中所有对话框窗口的父类,是一种容器类型的组件
- QDialog继承于QWidget类,如下图所示:
QWidget和QDialog有什么不同
QDialog:
- QDialog是定制了窗口式样的特殊的QWidget
- QDialog只能作为专用的交互窗口
- QDialog不能作为子部件,嵌入其它容器中
QWidget:
- QWidget如果没有父组件,则将会成为一个主窗口,
- QWidget如果有父组件,则将成为其父组件的子部件,嵌入到其父组件里
代码试验: QWidget和QDialog区别
代码1:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.resize(300,300); QDialog d(&w); d.resize(150,150); w.show(); d.show(); return a.exec(); }
效果:
可以看到,对话框始终都是作为独立的交互窗口
代码2:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w1; w1.resize(300,300); QWidget w2(&w1); w2.resize(150,150); w1.show(); w2.show(); return a.exec(); }
效果:
可以看到只出现了一个窗口,并没有出现第二个窗口
对话框类型
模态对话框
- 属于阻塞式调用,指没有关闭该对话框之前,是无法与其它任何窗口进行交互的
- 用于依赖用户选择的场合,比如:选项设置,消息提示,字体设置等
- 在栈上创建模态对话框是最简单常用的方式
- 使用exec()进入对话框的消息循环,从而实现阻塞式调用
实验代码:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.resize(300,300);
w.show(); QDialog d(&w); d.resize(150,150); d.exec(); //进入对话框d的消息循环,从而实现阻塞式调用 return a.exec(); }
非模态对话框
- 属于非阻塞调用,指出现该对话框时,也可以与父窗口进行交互
- 用于特殊功能设置的场合,比如:查找操作
- 一般情况下非模态对话框需要在堆上创建,避免自动被摧毁
- 非模态对话框需要通过setAttribute()成员函数指定Qt::WA_DeleteOnClose属性
- Qt::WA_DeleteOnClose表示:退出窗口后,让Qt自动摧毁这个对话框
- 使用show()来显示对话框窗口,从而实现非阻塞调用
实验代码:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.resize(300,300); w.show(); QDialog *d = new QDialog(&w); d->setAttribute(Qt::WA_DeleteOnClose); d->resize(150,150); d->show(); return a.exec(); }
混合模态对话框
- 在非模态对话框的基础上调用QDialog::setModal(true)成员函数实现
实验代码:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.resize(300,300); w.show(); QDialog *d = new QDialog(&w); d->setAttribute(Qt::WA_DeleteOnClose); d->setModal(true); d->resize(150,150); d->show(); return a.exec(); }
对话框返回值处理
- 只有模态对话框才有返回值概念
- QDialog::exec()的返回值作为交互结果
-使用void QDialog::done ( int r ) 作为交互结果,将r值返回给exec()
-返回值为QDialog::Accepted时,表示用户操作成功
-返回值为QDialog::Rejected时,表示用户操作失败
-也可以自定义返回数值
非模态示例-制作查找对话框
由于查找对话框每次打开时,都会有上次状态的内容,所以需要用到QSharedPointer动态指针
QFindDialog对话框:
class QFindDialog : public QDialog { private: QLabel label; QLineEdit edit; QPushButton ButtonFind; QPushButton ButtonCancel; QCheckBox CkBoxCase; QGroupBox GrpBoxDir; QRadioButton PreButton; QRadioButton NextButton; QGridLayout GLayout; QHBoxLayout HBLayout; public: QFindDialog(QWidget* parent=0); }; QFindDialog::QFindDialog(QWidget *parent) : QDialog(parent,Qt::WindowCloseButtonHint|Qt::Drawer), label("查找内容:",this), edit(this), ButtonFind("查找下一个",this), ButtonCancel("取消",this), CkBoxCase("区分大小写",this), GrpBoxDir("方向",this), PreButton("向上",this), NextButton("向下",this), GLayout(this), HBLayout(this) { PreButton.setChecked(true); HBLayout.addWidget(&PreButton); HBLayout.addWidget(&NextButton); GrpBoxDir.setLayout(&HBLayout); //将单选按钮添加到QGroupBox分组框 GLayout.setSpacing(5); GLayout.addWidget(&label,0,0); GLayout.addWidget(&edit,0,1); GLayout.addWidget(&ButtonFind,0,2); GLayout.addWidget(&CkBoxCase,1,0); GLayout.addWidget(&GrpBoxDir,1,1); GLayout.addWidget(&ButtonCancel,1,2); this->setLayout(&GLayout); setWindowTitle("查找"); }
widget窗口文件:
class Widget : public QWidget { Q_OBJECT private : QPushButton btn; QSharedPointer<QFindDialog> FindDialog; //动态指针 private slots: void onclickedbtn(); public: explicit Widget(); }; Widget::Widget(): btn("查找",this), FindDialog(new QFindDialog(this)) { connect(&btn,SIGNAL(clicked()),this,SLOT(onclickedbtn())); }
void Widget::onclickedbtn() { FindDialog->show(); //显示查找对话框 }
效果:
下章学习:9.QT-标准对话框
人间有真情,人间有真爱。