窗口概述
我们之前学过的代码都是基于QWidget控件,而QWidget更多情况下是作为别的窗口的一部分。
像菜单栏,工具栏,状态栏这些跟窗口有关的,一般不把它们划分为控件。
菜单栏
一个主窗口最多只有一个菜单栏。
创建菜单栏
它的创建方式有两种:
1.
QMenuBar * menuBar() const
2.在堆上动态创建:
其中对于第二种创建方式:
如果我们创建项目的时候,勾选了自动生成ui文件,那么这种方式创建是没问题的。但是如果我们勾选了自动生成ui文件,那么这种方式创建就会引起内存泄漏。
因为自动生成ui文件的请款下,Qt其实已经帮我们生成了一个MenuBar了,在QtDesigner中可以看到:
在这个对象树中已经有一个menubar了。如果我们自己又创建了一个新的 menubar,然后将新的menubar设置到MainWindow的对象树中,那么旧的menubar就会脱离Qt的对象树,也就意味着后续无法对这个对象进行释放了。
不过这里造成的内存泄露对于客户端相比于服务器来说还好,因为现在的计算机内存都比较充裕,但是对于服务器来说就很致命了,因为服务器要处理很多请求,如果每个请求泄漏一点,那么积累下来就会泄漏很多,另外服务器一般都要求7 * 24小时运行。
关于 QMainWindow类 提供的 menuBar() 函数:
在菜单栏中添加菜单
上述代码直接运行后是什么都没有的。
我们需要创建菜单,并通过 QMenu 提供的 addMenu() 函数 来添加菜单。
同时需要用到Menu类
创建菜单项
QAction 可以给菜单栏使⽤, 也可以给⼯具栏使⽤
在菜单项之间添加分割线
当菜单栏的单项很多时,就可以通过分割线进行分组。
添加图标
添加图标,一样还是建议使用qrc文件管理的方式来添加。
给菜单添加:
我们发现给QMenu设置图标的话,那么它原本的文本就会被图标给覆盖。
我们给子菜单添加图标再看看
我们发现给子菜单添加图标就不会出现文本被覆盖的情况。
⼯具栏
QToolBar的基本使用
一个窗口可以有多个工具栏,也可以没有。
典型的工具栏展示的一般是图标而不是文本。
我们可以设置图标
可以看到,如果QAction出现在工具栏上,也会产生图标覆盖文本的情况。
不过此时这个文本会议tooltip的方式存在
这个tooltip也可以手动设置。
工具栏和菜单栏往往是搭配使用的,工具栏中的QAction也可以出现在菜单栏中。
有这样一个问题:
设置停靠位置
先创建多个工具栏,方便观察。
⽅式⼀:创建⼯具栏的同时指定其停靠的位置。
⽅式⼆:使⽤ QToolBar类 提供的 setAllowedAreas()函数 设置停靠位置。
设置浮动属性
void setFloatable (bool floatable)
程序运行后,鼠标长按那一排点点即可拖动窗口。
设置移动属性
void setMovable(bool movable)
设置了不能移动后,那些点点都不见了,说明都不能拖动了。
状态栏
状态栏的创建
在状态栏中显⽰实时消息
showMessage如果timeout = 0的话,就会一直显示。
timeout的单位是ms。
在状态栏中添加控件
在状态栏中可以显⽰永久消息,此处的永久消息是通过 标签 来显⽰的
这里看到消息是显示在左侧的,我们也可以设置显示在右侧
当然我们也可以添加按钮,进度条这些。
注意
对于Qt的内置类,我们通过setXXX,addXXX这样的接口把这些内置类对象设置或者添加到比如对象A中,那么它们的生命周期也将由对象A来管理。
浮动窗⼝
浮动窗⼝的创建
浮动窗⼝的创建是通过 QDockWidget类 提供的构造⽅法 QDockWidget()函数 动态创建的
我们可以通过鼠标拖动这个浮动窗口的位置。也可以通过这个x号关闭
我们也可以把这个窗口嵌套设置进其它窗口中
设置停靠的位置
不过它依然可以自由停靠。
对话框
对话框介绍
我们在创建项目的时候,可以选择Bass Class:
通过这样的方式创建出来的程序窗口和QWidget非常相似。
在实际开发中,更多的情况并不是在这里继承自QDialog,而是继承其它的类,然后在代码中创建额外的类,让这个类继承QDialog。
所以这里演示的时候我们还是以QWidget为例
对话框的内存泄漏问题
关于这个代码
虽然我们new了一个对话框,并且将它放到了对象树中,但是这里我们需要注意:
我们只是把它挂到了Widget这个窗口中,那么只有当Widget销毁时,这个对话框才会销毁。
我们每次点击按钮就会生成一个对话框,虽然点击窗口上的❌就可以这个对话框关闭,此时这里它的资源并没有释放,因此就会导致内存泄漏了。
在上述代码中
Qt显然也考虑到了这个问题,因此给我们提供了一种很方便的解决方案:
自定义对话框
自定义对话框的方式有两种。
比如刚刚的代码,就是其中一种:用代码的方式自定义对话框,比如添加一个布局管理器
第二种方式:通过图形化界面的方式
在界面文件右键新建:
这样我们就可以通过图形化界面的方式来自定义对话框了。
在界面文件这里也多了相应的文件。
我们用两个按钮来进行区分
实现对应的槽函数
不要忘记包含头文件
对话框的分类
对话框分为模态对话框和非模态对话框。
模态对话框:弹出对话框的时候,此时用户无法操作父窗口,必须先完成对话框中的操作。
一般用在特别关键的场合,此时需要用户做出决策的场景。
非模态对话框: 弹出对话框的时候,用户可以操作父窗口。
一般用在不是特别关键的场景。
我们之前演示的对话框默认就是非模态对话框。
使用模态对话框,其实只要将show换成exec即可。
此时就是模态对话框了。
模态对话框最好不要频繁使用,不然会影响用户的体验。
false就是非模态,反之就是模态。
Qt内置对话框
Qt 提供了多种可复⽤的对话框类型,即 Qt 标准对话框。Qt 标准对话框全部继承于 QDialog类。
常用的标准对话框:
消息对话框 QMessageBox
问题提示对话框
这里的按钮有很多种:
还有前面的Icon
颜⾊对话框 QColorDialog
颜⾊对话框的功能是允许⽤⼾选择颜⾊。继承⾃ QDialog 类。
获取用户选择颜色/设置初始的颜色
演示:
同时,getColor还可以设置用户打开对话框时的初始颜色。
我们还可以使用QSS来通过用户选择的颜色来设置窗口的颜色。
void MainWindow::on_pushButton_clicked()
{
QColorDialog* dialog = new QColorDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
//dialog->show();
QColor color = dialog->getColor(QColor(237,28,36)); // 这是一个静态方法,设置初始颜色为红色
qDebug() << color;
QString colors = "background-color: rgb(" + QString::number(color.red()) + ","
+ QString::number(color.green()) + "," + QString::number(color.blue()) + ");";
this->setStyleSheet(colors);
}
⽂件对话框 QFileDialog
⽂件对话框⽤于应⽤程序中需要打开⼀个外部⽂件或需要将当前内容存储到指定的外部⽂件
打开⽂件
其中getOpenFileName是一个静态方法,它可以自动帮我们创建一个对话框,并且它的返回值是一个QString,也就是我们目标文件的路径。
getOpenFileName的参数
从左至右分别是 父指针 文件对话框的标题 对话框的初始路径 只保留什么格式的文件
保存文件
这里的对话框和打开是略有不同的。
不过我们这里并没有实现其它逻辑,所以点击了保存也不会有什么反应。
字体对话框 QFontDialog
Qt 中提供了预定义的字体对话框类 QFontDialog,⽤于提供选择字体的对话框部件。
输⼊对话框 QInputDialog
Qt 中提供了预定义的输⼊对话框类:QInputDialog,⽤于进⾏临时数据输⼊的场合。
数据的类型可以是整数,浮点数,字符串等等
同样也提供了静态函数
比如: