一.窗口概述
Qt 窗口是通过 QMainWindow 类来实现的。
QMainWindow是一个为用户提供主窗口程序的类,继承QWidget类,并且提供一个预定义的布局。包含一个菜单栏(menu bar) ,多个工具栏(tool bars) ,多个浮动窗口 (铆接部件)(dock widgets ),一个状态栏(status bar) ,一个中心部件(central widget)。
二.菜单栏
一个主窗口最多只有一个菜单栏,由QMenuBar类实现,位于主窗口顶部、主窗口标题栏的下面。
菜单栏中包含多个菜单,每个菜单又包含多个菜单项。
1.创建菜单栏
创建MainWindow类型的Qt项目后,Qt编辑界面就会多出一行菜单栏:
可以在此处直接添加菜单,及其菜单项。
同样我们也可以通过代码方式来创建菜单栏,菜单,及其菜单项。
cpp
//创建菜单栏
QMenuBar* menubar = new QMenuBar();
this->setMenuBar(menubar);
//创建菜单
QMenu* menu = new QMenu("文件");
//添加菜单到菜单栏
menubar->addMenu(menu);
//创建菜单项
QAction* action1 = new QAction("保存");
QAction* action2 = new QAction("新建");
QAction* action3 = new QAction("关闭");
//添加菜单项到菜单
menu->addAction(action1);
menu->addAction(action2);
menu->addAction(action3);
对应的头文件都要进行包含,结果如下:
同时我们也可以在菜单中添加子菜单,只需要调用父菜单的addMenu函数添加子菜单即可。
此外,在创建菜单栏时,更推荐采用如下方式进行:
QMenuBar menubar = this->menuBar();
这是因为当在创建QMainWindow项目时,如果勾选了自动创建.ui文件,那么系统就会自动帮我们生成一个QMenuBar对象 ,此时如果在代码中通过new方式创建菜单栏时,等于是创建的一个新的QMenuBar对象去抢占原对象在对象树上的位置 ,导致原对象无法被释放,从而导致内存泄漏。
通过上述方式来创建QMenuBar对象,有两种好处:
- 如果QMenuBar已经存在,就直接获取它并返回。
- 如果QMenuBar不存在,就创建一个新的并返回。
2.添加快捷键
在菜单栏中,还可以使用Alt+对应字母的方式实现快捷键操作:
而在代码中实现这些快捷键非常简单,只需要在创建菜单时,同菜单名一起添加快捷键即可:
QMenu* menu = new QMenu("文件(&F)");
注意需要加上"&",结果如下:
同理,如果要给菜单里的菜单项 也添加快捷键,同样是在创建菜单项时,加上**&+键名**即可。
3.添加分割线
通过QMenu中的addSeparator函数,可以在两个菜单项中间添加分割线:
cpp
//添加菜单项到菜单
menu->addAction(action1);
menu->addSeparator();
menu->addAction(action2);
menu->addSeparator();
menu->addAction(action3);
注意该函数的位置也必须处于addAction函数的中间,才能有用,结果如下:
三.工具栏
工具栏是应用程序中集成各种功能实现快捷键使用的一个区域。可以有多个,也可以没有,它并不是应用程序中必须存在的组件。
1.创建工具栏
调用 QMainWindow类的 addToolBar() 函数创建工具栏,每增加一个工具栏都需要调用该函数。
其中工具栏里的各个工具,与上述菜单项一样,都是使用QAction类,下面代码创建一个工具栏:
cpp
//创建工具栏
QToolBar* toolbar = new QToolBar();
this->addToolBar(toolbar);
//创建工具
QAction* action1 = new QAction("保存");
QAction* action2 = new QAction("赋值");
//添加工具至工具栏
toolbar->addAction(action1);
toolbar->addAction(action2);
注意这里工具栏并不会在项目创建时由系统默认生成,所以需要自己创建,结果如下:
2.工具栏移动
在某些软件中,工具栏是可以进行移动的,Qt中的工具栏就可以:
能够看出在工具栏最前边有几个小黑点,这就是该工具栏可以移动的标准,此外,对于工具栏移动有很多操作。
工具栏允许停靠的区域 由 QToolBar类 提供的 **allowAreas()**函数决定,其中可以设置的位置包括:
- Qt::LeftToolBarArea 停靠在左侧
- Qt::RightToolBarArea 停靠在右侧
- Qt::TopToolBarArea 停靠在顶部
- Qt::BottomToolBarArea 停靠在底部
- Qt::AllToolBarAreas 以上四个位置都可停靠
有两种方式来设置工具栏的停靠方式:
//创建工具栏的同时,指定其停靠位置
this->addToolBar(Qt::LeftToolBarArea,toolbar);
//创建工具栏之后,使用函数来指定其停靠位置
toolbar->setAllowedAreas(Qt::LeftToolBarArea);
此外,我们还可以设置工具栏的可移动和可浮动(停靠在窗口任意位置)属性,相关函数如下:
void setFloatable (bool floatable);
参数: true:浮动 false:不浮动
void setMovable(bool movable);参数: true:移动 false:不移动
三.状态栏
状态栏是应用程序中输出简要信息的区域。一般位于主窗口的最底部 ,一个窗口中最多只能有⼀个状态栏。在 Qt 中,状态栏是通过 QStatusBar类来实现的。 在状态栏中可以显示的消息类型有:
- 实时消息:如当前程序状态
- 永久消息:如程序版本号,机构名称
- 进度消息:如进度条提示,百分百提示
1.创建状态栏
状态栏与菜单栏一样,同样会在项目勾选自动生成ui文件时,由系统自动生成,因为创建方式推荐与菜单栏一致:
cpp
//创建状态栏
QStatusBar* statusbar = this->statusBar();
statusbar->showMessage("这是一个状态栏");
结果如下:
状态栏中可以添加各种控件,这里就不进行分享了。
四.浮动窗口
在 Qt 中,浮动窗口也称之为铆接部件。浮动窗口是通过 QDockWidget 类来实现浮动的功能。浮动窗口一般是位于核心部件的周围,可以有多个。
1.创建浮动窗口
浮动窗口的创建是通过 QDockWidget 类提供的构造方法 **QDockWidget()**函数动态创建的。
cpp
//创建浮动窗口
QDockWidget* dockWidget = new QDockWidget();
dockWidget->setWindowTitle("浮动窗口");
//初始设置浮动窗口停靠在左侧
this->addDockWidget(Qt::LeftDockWidgetArea,dockWidget);
结果如下:
此外,浮动窗口同样可以使用 QDockWidget 类中提供 setAllowedAreas() 函数设置其允许停靠的位置:
Qt::LeftDockWidgetArea 停靠在左侧
Qt::RightDockWidgetArea 停靠在右侧
Qt::TopDockWidgetArea 停靠在顶部
Qt::BottomDockWidgetArea 停靠在底部
Qt::AllDockWidgetAreas 以上四个位置都可停靠
2.添加控件
想要在浮动窗口中添加控件,并非像状态栏一样,进行直接添加,而是需要先在浮动窗口中添加一个Qwidget作为控件的载体。
cpp
//创建一个QWidget
QWidget* qWidget = new QWidget();
dockWidget->setWidget(qWidget);
//添加控件
QPushButton* button = new QPushButton(qWidget);
button->setText("按钮");
结果如下:
五.对话框
对话框是 GUI 程序中不可或缺的组成部分。⼀些不适合在主窗口实现的功能组件可以设置在对话框中。对话框通常是⼀个顶层窗口,出现在程序最上层,用于实现短期任务或者简洁的用户交互。
Qt中,对话框以QDialog 作为父类,我们可以在创建项目时,直接选择创建一个QDialog类的项目 ,也可以在程序中,创建一个类继承自QDialog,来实现创建对话框的目的 ,在实际应用中,更推荐使用后者。
下面来实现一段代码,使得点击按钮后创建一个对话框:
cpp
void MainWindow::on_pushButton_clicked()
{
QDialog* dialog = new QDialog(this);
dialog->show();
}
结果如下:
QDialog实际上也是QWidget的子类,QWidget的各种属性方法同样能够使用。
下面展示一种情况:
能够看出,每点击一次按钮,就会创建一个新的对话框,即创建一个新的QDialog对象。此时如果用户打开的对话框数量过多,或者对话框的内存太大,就可能出现内存泄漏 的问题。因此,建议在用户点击对话框的关闭按钮时,将对应的对话框进行delete。
要实现这种做法,就需要将delete和关闭按钮的信号关联起来,这一点Qt已经帮我们实现了:
dialog->setAttribute(Qt::WA_DeleteOnClose);
只需要设置一下对话框的属性即可。
上述对话框中没有任何控件,如果想要添加,可以自定义一个类,继承自QDialog ,进而在该类的构造函数中添加各种控件。除此之外,也可以直接新建一套Qt设计界面 ,选择QDialog模版:
1.对话框分类
对话框分为模态对话框 和非模态对话框。
模态对话框指的是:显示后无法与父窗口进行交互 ,是⼀种阻塞式的对话框。使用QDialog::exec() 函数调用。
非模态对话框显示后独立存在,可以同时与父窗口进行交互 ,是⼀种非阻塞式对话框,使用**QDialog::show()**函数调用。
非模态对话框⼀般在堆上创建,这是因为如果创建在栈上时,弹出的非模态对话框就会⼀闪而过。同时还需要设置 Qt:WA_DeleteOnClose 属性,避免内存泄漏。
2.Qt内置对话框
Qt 提供了多种可复用的对话框类型,即 Qt 标准对话框。Qt 标准对话框全部继承于 QDialog 类。
(1)消息对话框
消息对话框是应用程序中最常用的界面元素,由QMessageBox类 提供。消息对话框主要用于为用户提示重要信息,强制用户进行选择操作。
QMessageBox类中定义了静态成员函数setIcon(),可以直接调用创建不同风格的消息对话框:
Question :用于正常操作过程中的提问
Information :用于报告正常运行信息
Warning :用于报告非关键错误
Critical :用于报告严重错误
QMessageBox类还定义了可以自定义消息对话框按钮的枚举 类型,通过setStandarButtons函数添加,如下是按钮的类型:
这里分享一个创建消息对话框最简单的一种方式:
QmessageBox::对话框风格(父节点,对话框标题,对话框文本,对话框按钮) ;
其中对话框按钮可以省略。
此种方式创建的消息对话框,仅用于一次性提示操作,如果想添加更多按钮或操作,则还是建议定义出对话框对象来进行操作。
(2)颜色对话框
颜色对话框的功能是允许用户选择颜色。由QColorDialog类提供,继承自 QDialog 类。
颜色对话框,同样有一个快速创建的方法,通过静态函数来直接创建:
QColorDialog::getColor(默认颜色,父对象,对话框标题,设置颜色(可选))
//打开颜色选择对话框,并返回一个QColor对象,该对象就是用户选择的颜色。通过获取该对象,就能够进行各种颜色设置操作。
例如创建一个默认颜色为红的颜色对话框:
QColorDialog::getColor(Qt::red,this,"颜色调节");
结果如下:
(3)文件对话框
文件对话框用于应用程序中需要打开⼀个外部文件或需要将当前内容存储到指定的外部文件。由QFileDialog类提供。
1、打开文件(⼀次只能打开⼀个文件)
QString getOpenFileName()//返回文件路径
2、打开多个文件(⼀次可以打开多个文件)
QStringList getOpenFileNames()//返回文件路径列表
3、 保存文件
QString getSaveFileName()//返回文件路径
参数说明:
参数1:parent 父节点
参数2:caption 对话框标题
参数3:dir 默认打开的路径
参数4:filter 文件过滤器(按照文件后缀)
其中处理指定父节点之外,其它参数都是可选择的。
下面展示一下打开文件操作:
cpp
void MainWindow::on_pushButton_clicked()
{
QFileDialog::getOpenFileName(this);
}
结果如下:
(4)字体对话框
Qt 中提供了预定义的字体对话框类 QFontDialog,用于提供选择字体的对话框部件。
通过QFontDialog内部提供的静态函数getFont就可以打开字体对话框:
cpp
void MainWindow::on_pushButton_clicked()
{
bool flag = false;
QFontDialog::getFont(&flag);
//QFontDialog::getFont(&flag,QFont("黑体",14));
}
由于该函数第一个参数为bool类型,所以需要定义一个参数传入,参数设为false或true均可。
该函数会返回一个字体类对象,包含用户通过字体对话框所设置的各种属性信息。
可以通过仅传入bool类型参数直接打开字体对话框:
也可以额外传入一个字体类对象,使得打开的字体对话框为传入对象的属性:
(5)输入对话框
Qt 中提供了预定义的输入对话框类:QInputDialog ,用于用户进行临时数据输入的场合。
QInputDialog同样提供了几个静态函数:
双精度浮点型输⼊数据对话框
double getDouble ();
2、整型输⼊数据对话框
int getInt ();
3、选择条目型输入数据框
QString getItem () ;
参数说明:
parent:父节点
title:对话框标题
label:对话框标签
函数对应的返回值即为用户输入的数据。
在条目型输入数据框中,还存在一个类型为QStringList类型 的参数,这是一个列表,与STL中的vector和list类似,是Qt自己封装的容器,通过传入一个该类型的参数,用户不仅可以手动输入,还可以选择该容器中存储的条目信息。
下面展示一下整型输入对话框的实现:
cpp
void MainWindow::on_pushButton_clicked()
{
QInputDialog::getInt(this,"整型输入对话框","整型");
}
结果如下: