窗口部件
QT提供的默认基类只有QMainWindow、QWidget、和QDialog这三种,这三种窗体也是用的最多的,QMainWindow是带有菜单栏和工具栏的主窗口类,QDialog是各种对话框的基类,而他们全部继承自QWidget。不仅如此,所以的窗口部件都继承自QWidget,继承关系如图所示。
使用规则:
- 如果需要嵌入到其他窗体中,则基于QWidget创建。
- 如果是主窗体,则基于QMainWindow创建。
- 如果是顶级对话框,则基于QDialog创建。
1. 基础窗口部件QWidget
QWidget类是所有用户界面对象的基类,被称为基础窗口部件。
像主窗口、对话框、标签、还有按钮、文本输入框等都是窗口部件。这些部件可以接受用户输入,显示数据和状态信息,并且在屏幕上绘制自己。QT把没有嵌入到其它部件的部件称为窗口,一般窗口都有边框和标题栏,就像程序中的widget和label一样,QMainWindow和大量的QDialog子类是最一般的窗口类型,窗口就是没有父部件的部件,所以又称为顶级部件。
QWidget有很多成员函数,但是它们中的一些有少量的直接功能:例如,QWidget有字体属性,但是自己从来不用。为很多继承它的子类提供了实际的功能,比如QLabel、QPushButton、QCheckBox等等。
没有父窗体的小部件始终是一个独立的窗口(顶级窗口部件)。非窗口的小部件为子部件,它们在父窗口中显示。Qt中大多数部件主要被用作子部件。例如:可以显示一个按钮作为顶层窗口,但大多数人更喜欢将按钮内置于其它部件,如QDialog。
上图显示了一个QGroupBox,里面包含了大量由QGridLayout布局的子控件。
2. QMainWindow
QMainWindow类提供一个有菜单条、工具栏、状态条的主应用程序窗口(例如:开发Qt常用的IDE-Visual Studio、Qt Creator等)。
一个主窗口提供了构建应用程序的用户界面框架。Qt拥有QMainWindow及其相关类来管理主窗口。
QMainWindow拥有自己的布局,我们可以使用QMenuBar(菜单栏)、QToolBar(工具栏)、QStatusBar(状态栏)以及QDockWidget(悬浮窗体),布局有一个可由任何种类小窗口所占据的中心区域。
例如:
3. 对话框QDialog
QDialog类是对话框窗口的基类。
对话框窗口是一个顶级窗体,主要用于短期任务以及和用户进行简要通讯。QDialog可以是模式的也可以是非模式的。QDialog支持扩展性并且可以提供返回值。它们可以有默认按钮。QDialog也可以有一个QSizeGrip在它的右下角,使用setSizeGripEnabled()。
注意:QDialog(以及其它使用Qt::Dialog类型的widget)使用父窗口部件的方法和Qt中其它类稍微不同。对话框总是顶级窗口部件,但是如果它有一个父对象,它的默认位置就是父对象的中间。它也将和父对象共享工具条条目。
1. 模态对话框和非模态对话框
QDialog类是所有对话框窗口类的基类,对话框窗口是一个经常用来完成短小任务或者和用户进行简单交互的顶层窗口。按照运行对话框是否可以和该程序其它窗口交互,对话框被称为:模态和非模态的。
- 模态对话框
阻塞同一应用程序中其它可视窗口输入的对话框。模式对话框有自己的事件循环,用户必须完成这个对话框中的交互操作,并且关闭了它之后才能访问应用程序中的其它任何窗口。模式对话框仅阻止访问与对话相关联的窗口,允许用户继续使用其它窗口中的应用程序。
显示模态对话框最常见的方法是调用其exec()函数,当用户关闭对话框,exec()将提供一个有用的返回值,并且这时流程控制继续从调用exec()的地方进行。通常情况下,要获得对话框关闭并返回相应的值,我们连接默认按钮,例如:”确定”按钮连接到accept()槽,”取消”按钮连接到reject()槽。另外我们也可以连接done()槽,传递给它Accepted或Rejected。
- 非模态对话框
和同一个程序中其它窗口操作无关的对话框。在文字处理中的查找和替换对话框通常是非模式的,允许用户同时与应用程序的主窗口和对话框进行交互。调用show()来显示非模式对话框,并立即将控制返回给调用者。
如果隐藏对话框后调用show()函数,对话框将显示在其原始位置,这是因为窗口管理器决定的窗户位置没有明确由程序员指定,为了保持被用户移动的对话框位置,在closeEvent()中进行处理,然后在显示之前,将对话框移动到该位置。
-
"半模式"对话框
调用setModal(true)或者setWindowModality(),然后show()。有别于exec(),show() 立即返回给控制调用者。
对于进度对话框来说,调用setModal(true)是非常有用的,用户必须拥有与其交互的能力,例如:取消长时间运行的操作。如果使用show()和setModal(true)共同执行一个长时间操作,则必须定期在执行过程中调用QApplication ::processEvents(),以使用户能够与对话框交互(可以参考QProgressDialog)。
2. 多窗口切换
Qt使用信号与槽机制来完成对象之间的协同操作,简单来说,信号与槽都是函数,比如单击窗口上一个按钮弹出一个对话框,那么可以将这个按钮的单击信号和自定义的槽函数关联起来,在这个槽中创建一个对话框来显示他。
void Widget::on_pushButton_clicked()
{
QDialog *dialog =new QDialog();
dialog->exec();
}
3. 自定义对话框
这里可以自定义一个对话框,来实现与主界面的切换,比如先弹出来登录界面,之后点击按钮来实现切换到主界面。
第一步,添加登录框,首先添加QT设计师界面类,界面模版和类名选好后,加入控件,如图
第二步,设计信号与槽,在退出程序的按钮上实现信号与槽,如图:
F4进入信号与槽编辑模式,然后左键拖动到要关联的控件,之后在弹出的对话框中选择信号与槽,之后可以按F3退出。之后是进入主界面按钮的信号与槽,右键转到槽,在里面写上accept(),这个accept()函数就是QDialog类的一个槽,对于一个使用exec函数实现的模态对话框,执行这个槽就会隐藏这个模态对话框,并返回QDialog::Accepted值,这里就是要使用这个值来判断是哪个按钮被按下了,与其对应的还有一个reject()槽,它可以返回一个QDialog::Rejected值,前面的“退出程序”按钮也可以关联这个槽。
第三步,设置主界面 main.cpp函数如下:
#include "widget.h"
#include <QApplication>
#include "mydialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
MyDialog dialog; //新建自定义MyDialog对象
if(dialog.exec() == QDialog::Accepted) //判断dialog执行结果
{
w.show(); //如果按下了“进入主界面”按钮,则进入主界面
return a.exec();
}
else return 0; //否则退出程序
}
dialog.exec()先显示模态对话框,如果点击了按钮,由于设置了进入主界面的槽是acccept(),所以返回值= QDialog::Accepted是符合要求的,就会消失登陆界面转到显示主界面正常执行。
4. 主界面返回登录框
在主界面.ui文件里加上重新登录按钮和退出。退出的信号与槽和前面的退出一样,F4关联close()即可;重新登录的按钮先创建clicked()的槽,并改成如下:
#include "widget.h"
#include "ui_widget.h"
#include <QDialog>
#include "mydialog.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{ //按下重新登录先隐藏当前界面
close();
MyDialog dlg;
//显示登陆界面,如果返回值等于这个,也就是点击了登录,那么程序显示主界面,如果不是,由于此时没有可以显示的界面就会完全退出程序
if(dlg.exec() ==QDialog::Accepted)show();
}