概述
对话框是与用户进行简短交互的顶层窗口。
QDialog 是 Qt 对话框钟所有对话框的基类
QDialog 继承于 QWidget 是一种容器类型的组件。
QDialog 的意义
- QDialog作为一种专用的交互窗口而存在
- QDialog不能作为子部件嵌入其它容器中
- QDialog是定制了窗口式样的特殊的QWidget
QDialog 和 QWidget 的区别
#include <QDialog>
#include <QWidget>
#include <QApplication>
int main(int argc,char* argv[])
{
QApplication a(argc,argv);
QDialog dlg;
dlg.setWindowTitle("dlg");
dlg.show();
QWidget widget;
widget.setWindowTitle("widget");
widget.show();
return a.exec();
}
为 QDialog 设置父组件为 QWidget
#include <QDialog>
#include <QWidget>
#include <QApplication>
int main(int argc,char* argv[])
{
QApplication a(argc,argv);
QWidget widget;
QDialog dlg(&widget);
dlg.setWindowTitle("dlg");
dlg.show();
widget.setWindowTitle("widget");
widget.show();
return a.exec();
}
结果发现 QDialog 还是位于 QWidget 的上层,说明 QDialog 只能是顶层的部件
设置 QWidget 的父组件为 QDialog
#include <QDialog>
#include <QWidget>
#include <QApplication>
int main(int argc,char* argv[])
{
QApplication a(argc,argv);
QDialog dlg;
QWidget widget(&dlg);
dlg.setWindowTitle("dlg");
dlg.show();
widget.setWindowTitle("widget");
widget.show();
return a.exec();
}
结果 QWidget 被设置到 QDialog ,因为内容为空所以在视觉上只有一个 dialog。
对话框的类型
模态对话框( QDialog::exec() )
-
显示后无法与父窗口进行交互
-
是一种阻塞式的对话框调用方式
非模态对话框( QDialog::show() )
显示后独立存在可以同时与父窗口进行交互是一种非阻塞式的对话框调用方式
一般情况下
- 模态对话框用于必须依赖用户选择的场合( 80% )
- 消息提示,文件选择,打印设置,等
非模态对话框用于特殊功能设置的场合( 20% )
- 查找操作,属性设置,等
#include "dialog.h"
#include <QDebug>
Dialog::Dialog()
:btn1(this),btn2(this),btn3(this)
{
setFixedSize(180,220);
btn1.move(30,20);
btn1.setText("btn1");
btn2.move(30,70);
btn2.setText("btn2");
btn3.move(30,120);
btn3.setText("btn3");
connect(&btn1,SIGNAL(clicked()),this,SLOT(btn1_clicked()));
connect(&btn2,SIGNAL(clicked()),this,SLOT(btn2_clicked()));
connect(&btn3,SIGNAL(clicked()),this,SLOT(btn3_clicked()));
}
Dialog::~Dialog()
{
}
void Dialog::btn1_clicked()
{
qDebug()<<"Btn1 clicked";
QDialog* dlg = new QDialog(this);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setWindowTitle("exec");
dlg->exec();
qDebug()<<"Btn1 end";
}
void Dialog::btn2_clicked()
{
// 指针在函数内部调用函数结束的时候指针占用的内存资源没有被释放
// 小技巧: Qt::WA_DeleteOnClose 防止内存泄漏
qDebug()<<"Btn2 clicked";
QDialog* dlg = new QDialog(this);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setWindowTitle("show");
dlg->show();
qDebug()<<"Btn2 end";
}
void Dialog::btn3_clicked()
{
qDebug()<<"Btn3 clicked";
// 混合属性设置,在堆上面创建 ,调用 show ,效果和 exec 类似
QDialog* dlg = new QDialog(this);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setModal(this);
dlg->show();
qDebug()<<"Btn3 end";
}
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QPushButton>
class Dialog : public QDialog
{
Q_OBJECT
private:
QPushButton btn1;
QPushButton btn2;
QPushButton btn3;
private slots:
void btn1_clicked();
void btn2_clicked();
void btn3_clicked();
public:
Dialog();
~Dialog();
};
#endif // DIALOG_H
DIalog 对话框的使用
只有模态对话框才有返回值的概念,模态对话框的返回值用于表示交互结果。
QDialog::exec()的返回值为交互结果void QDialog::done(int i)关闭对话框并将参数作为交互结果
- QDialog::Accepted-用户操作成功
- QDialog::Rejected-用户操作失败
#include "dialog.h"
#include <QDebug>
Dialog::Dialog()
:btn1(this),btn2(this),btn3(this)
{
setFixedSize(180,220);
btn1.move(30,20);
btn1.setText("btn1");
btn2.move(30,70);
btn2.setText("btn2");
btn3.move(30,120);
btn3.setText("btn3");
connect(&btn1,SIGNAL(clicked()),this,SLOT(btn1_clicked()));
connect(&btn2,SIGNAL(clicked()),this,SLOT(btn2_clicked()));
connect(&btn3,SIGNAL(clicked()),this,SLOT(btn3_clicked()));
}
Dialog::~Dialog()
{
}
void Dialog::btn1_clicked()
{
done(Accepted);
}
void Dialog::btn2_clicked()
{
done(Rejected);
}
void Dialog::btn3_clicked()
{
done(520);
}
#include "dialog.h"
#include <QDebug>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
int r = w.exec();
if (r == QDialog::Accepted)
{
qDebug()<<"accepted";
}
else if ( r == QDialog::Rejected)
{
qDebug()<<"rejected";
}
else
{
qDebug()<<r;
}
// 以模态进行的时候要进行修改 exec 进入消息xu循环(不改会进入两次消息循环)
return r;//a.exec();
}
结果
总结
对话框分为模态对话框和非模态对话框
模态对话框是阻塞式的
模态对话框用于依赖用户交互结果的场合
非模态对话框是非阻塞式的
非模态对话框用于功能设置的场合