简介
对话框是 GUI 程序中不可或缺的组成部分。很多不能或者不适合放入主窗口的功能组件都必须放在对话框中设置。对话框通常会是一个顶层窗口,出现在程序最上层,用于实现短期任务或者简洁的用户交互。
Qt 中使用QDialog类实现对话框。就像主窗口一样,我们通常会设计一个类继承QDialog。QDialog(及其子类,以及所有Qt::Dialog类型的类)的对于其 parent 指针都有额外的解释:如果 parent 为 NULL,则该对话框会作为一个顶层窗口,否则则作为其父组件的子对话框(此时,其默认出现的位置是 parent 的中心)。顶层窗口与非顶层窗口的区别在于,顶层窗口在任务栏会有自己的位置,而非顶层窗口则会共享其父组件的位置。
对话框分为两种,一种是模态对话框、 另一种是非模态对话框。即阻塞和非阻塞对话框,而模态对话框又有两种:应用程序级别的和窗口级别的,分别指完成对话框之前阻塞整个应用和阻塞关联窗口。exec() 和 open() 分别为应用程序级别和窗口级别的模态对话框,show()则为非模态对话框。
用法
int QDialog::exec()
实现应用程序级别的模态对话框。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog dialog(this);
dialog.exec();
}
MainWindow::~MainWindow()
{
delete ui;
}
对话框出现,但是MainWindow窗口没有出现,关闭对话框,MainWindow窗口弹出来了。
简单一点讲就是在弹出模态对话框时,除了该对话框整个应用程序窗口都无法接受用户响应,处于等待状态,直到模态对话框被关闭。这时一般需要点击对话框中的确定或者取消等按钮关闭该对话框,程序得到对话框的返回值(即点击了确定还是取消),并根据返回值进行相应的操作,之后将操作权返回给用户。这个时候用户可以点击或者拖动程序其他窗口。
说白了就相当于阻塞同一应用程序中其它可视窗口的输入的对话框,用户必须完成这个对话框中的交互操作并且关闭了它之后才能访问应用程序中的其它窗口。
其实模态对话框的作用就是得到用户选择的结果,根据结果来进行下面的操作。
使用exec()方法显示出的对话框默认为应用程序级模态对话框。所有使用exec()方法显示对话框在窗口关闭前会阻塞整个程序所有窗口的响应。同时调用exec()方法后的代码也不会执行直到对话框关闭才会继续执行。在关闭对话框后exec()方法会返回Accepted或者Rejected,一般程序根据返回不同的结果进行相应的操作。
void QWidget::show()
实现非模态对话框。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog dialog(this);
dialog.show();
}
MainWindow::~MainWindow()
{
delete ui;
}
执行上面的代码,我们会发现窗口一闪而过,其原因是因为dialog被申明为一个局部变量,当用完之后就自动销毁,所以窗口show完之后立马就被释放。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog *dialog = new QDialog(this);
dialog ->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
执行上面程序弹出窗口不会一闪而过,因为new创建在堆上,不会自动销毁,需要手动delete。dialog ->setAttribute(Qt::WA_DeleteOnClose)的作用是当窗口关闭时,对话框释放。
void QDialog::open()
实现窗口级别的模态对话框。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog * dialog = new QDialog(this);
dialog->open();
}
MainWindow::~MainWindow()
{
delete ui;
}
半模态对话框,这样open()方法后的代码将会继续执行。
void setModal(bool modal)
通过setModal(true)实现show()的模态化,否则设为非模态。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog * dialog = new QDialog(this);
dialog->setModal(true);
dialog->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
QDialog::Accepted或QDialog::Rejected
因为QDialog::exec() 是有返回值的,其返回值是 QDialog::Accepted或者 QDialog::Rejected。
#include "dialog.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog dlg;
int n = dlg.exec();
if(n == QDialog::Accepted)
{
qDebug()<<"accept"; //点击确定按钮走这里
}
else if( n == QDialog::Rejected)
{
qDebug()<<"reject"; //点击取消按钮走这里
}
return a.exec();
}
首先,dlg.exec() 的意思是:执行模式对话框。按照之前对模式对话框的讲述,dlg.exec()的意思就是,显示子窗口,并在这里阻塞住,知道该窗口被关闭之后,才继续往下运行。n == QDialog::Accepted,当子窗口的那个按键按下后,发出accepted的信号,所以子窗口关闭,才继续往下执行,然后显示主窗口。