非模态对话框
我们依旧创建一个Qt Widgets Application 项目,然后自动生成文件和项目。
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog w();
w.show();
}
我们在MainWindow的构造函数里创建了QDialog类型的变量w。 然后调用w的show函数展示该对话框。 运行程序后会看到对话框w一闪而逝,然后创建了主窗口。 一闪而逝的而原因是w在MainWindow的构造函数里,构造函数结束w就被释放了。所以窗口就会一闪而逝。 即便是如下设置w的父窗口为mainwindow也无济于事
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog w(this);
w.show();
}
因为无论w的父窗口是谁,都会随着MainWindow构造函数的结束而释放。那么好用的办法就是通过new创建对话框,这样对话框的空间在堆上,就不会随着构造函数结束而被释放了。
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
auto w = new QDialog(this);
w->show();
}
用new创建QDialog 对象w,并且指明了this(MainWindow)为其父窗口,这样在父窗口关闭或者释放后,其子窗口也会释放。这个原理在之后会讲给大家,QT提供了对象树的机制,保证了父类被释放后子类都会被回收。所以这也是我们指明w的父窗口为MainWindow的意思,如果不指明就需要手动回收w。不回收就会造成内存泄漏。
再次运行就可以看到会弹出两个界面,一个是主窗口,一个是对话框了。 上面的方式创建的都是非模态对话框,所谓非模态对话框就是无论是否操作这个对话框都可以操作其他窗口。也就是说在非模态窗口弹出后并不阻塞其他窗口的消息传递。
模态对话框
模态对话框就是当该对话框弹出后会阻塞其他窗口的响应事件,必须先关闭该对话框,其他窗口才会继续响应事件。 我们改造MainWindow的构造函数,在里边创建一个模态对话框
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
auto w = new QDialog(this);
w->setModal(true);
w->show();
}
点击运行,弹出一个对话框和主窗口,点击主窗口没有任何反应,点击对话框关闭后才能点击主窗口,所以w就是一个模态对话框。 另外一个创建模态对话框的方式是这样的
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog w(this);
w.exec();
}
这种方式创建的对话框也是模态的,并且不会一闪而逝,主要原因是exec这个函数会阻塞其他界面响应事件。所以直到我们关闭这个对话框后,exec才返回,这样MainWindow的构造函数才继续往下执行。
窗口置顶
有时我们需要将对话框置顶,不论其是不是模态对话框我们都可以这么做
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
auto s = new QDialog(this);
s->setWindowFlag(Qt::WindowStaysOnTopHint);
s->show();
}
WindowStaysOnTopHint 表示窗口保持在最上边。类似的属性还有很多可以参考qt文档。
总结
目前总结了对话框的几种使用方法,模态和非模态,这并不复杂。 视频链接视频教程 源码链接https://gitee.com/secondtonone1/qt-learning-notes