QT-QMainWindow

QMainWindow

QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个停靠部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。

img

1.1 菜单栏

一个主窗口最多只有一个菜单栏

通过QMainWindow类menuBar())函数获取主窗口菜单栏指针,如果当前窗口没有菜单栏,该函数会自动创建一个。

Qt 并没有专门的菜单项类,只是使用一个QAction类,抽象出公共的动作。当我们把QAction对象添加到菜单,就显示成一个菜单项,添加到工具栏,就显示成一个工具按钮。用户可以通过点击菜单项、点击工具栏按钮、点击快捷键来激活这个动作。

 	// 设置窗口大小
    resize(1200, 800);
    // 设置窗口标题
	setWindowTitle("Qt");
    // 1、添加菜单栏 只能有一个
    QMenuBar * bar = new QMenuBar();
    setMenuBar(bar);
    // 创建菜单
    QMenu * fileMenu = bar->addMenu("文件");
    QMenu * editMenu = bar->addMenu("编辑");
    QMenu * consMenu = bar->addMenu("构建");
    QMenu * DebugMenu = bar->addMenu("调试");
    QMenu * AnalMenu = bar->addMenu("Analyze");
    QMenu * toolMenu = bar->addMenu("工具");
    QMenu * kongMenu = bar->addMenu("控件");
    QMenu * helpMenu = bar->addMenu("帮助");
    // 创建菜单项
    QAction * newAction = fileMenu->addAction("新建");
    QAction * openAction = fileMenu->addAction("打开");
    // 添加分割线
    fileMenu->addSeparator();
    QAction * closeAction = fileMenu->addAction("关闭");
    QAction * quitAction = fileMenu->addAction("退出");

    QAction * copyAction = editMenu->addAction("复制");
    QAction * pasteAction = editMenu->addAction("粘贴");
    editMenu->addSeparator();
    QAction * selallAction = editMenu->addAction("全选");

1.2 工具栏

主窗口的工具栏上可以有多个工具条,通常采用一个菜单对应一个工具条的的方式,也可根据需要进行工具条的划分。

调用QMainWindowd对象的成员函数addToolBar(),该函数每次调用都会创建一个新的工具栏,并且返回该工具栏的指针。

插入属于工具条的项,这时工具条上添加项也是用QAction。通过QToolBar类的addAction函数添加。

工具条是一个可移动的窗口,它的停靠区域由QToolBar的allowAreas决定,包括(以下值可以通过查帮助文档allowAreas来索引到):

  • Qt::LeftToolBarArea 停靠在左侧

  • Qt::RightToolBarArea 停靠在右侧

  • Qt::TopToolBarArea 停靠在顶部

  • Qt::BottomToolBarArea 停靠在底部

  • Qt::AllToolBarAreas 以上四个位置都可停靠

使用setAllowedAreas()函数指定停靠区域:

	// 2、工具栏 可以多个
    QToolBar * toolBar= new QToolBar(this);
    // 添加工具栏,工具栏默认上面,设置工具栏左边
    addToolBar(Qt::LeftToolBarArea, toolBar);
    // 设置浮动
    toolBar->setFloatable(false);
    // 设置只允许左右停靠
    toolBar->setAllowedAreas(Qt::LeftToolBarArea |Qt::RightToolBarArea);
    // 设置总开关
    toolBar->setMovable(false);
    // 存放小部件
    toolBar->addAction("新建");
    // 添加分割线
    toolBar->addSeparator();
    toolBar->addAction("打开");

1.3 状态栏

一个QMainWindow的程序最多只有一个状态栏。QMainWindow中可以有多个的部件都使用add…名字的函数,而只有一个的部件,就直接使用获取部件的函数,如menuBar。同理状态栏也提供了一个获取状态栏的函数statusBar(),没有就自动创建一个并返回状态栏的指针。

/ 3、状态栏 只有一个
    QStatusBar * stBar = new QStatusBar();
    // 添加状态栏
    setStatusBar(stBar);

    QLabel *label1 = new QLabel("左侧提示信息", this);
    stBar->addWidget(label1);
    QLabel *label2 = new QLabel("右侧提示信息", this);
    stBar->addPermanentWidget(label2);

1.4 停靠部件(铆接部件、浮动窗口)

停靠部件 QDockWidget,也称浮动窗口,可以有多个。

   // 4、 停靠部件 可以多个
    QDockWidget * dock = new QDockWidget("aaa", this);
    // 放置dock 位置 下端
    addDockWidget(Qt::BottomDockWidgetArea, dock);
	// 设置后期存放位置
	dock->setAllowedAreas(Qt::BottomDockWidgetArea|Qt::TopDockWidgetArea);

1.5 核心部件

	// 核心部件 只有一个
    QTextEdit * edit = new QTextEdit(this);
    setCentralWidget(edit);

1.6 使用UI文件创建窗口

创建工程的时选择UI界面

1.6.1 UI设计窗口介绍

image-20220729101851521

1.6.2 菜单栏

1.6.2.1 添加/删除菜单栏

默认情况下QMainWindow项目一创建就自带了菜单栏,可以在对象树窗口中,右键菜单栏对象,移除菜单栏:

image-20220729102035063

删除后也可以创建菜单栏,此时在对象树中右键MainWindow对象,菜单里边会多了创建菜单栏的功能

image-20220729102112027
1.6.2.2 添加菜单

点击菜单栏的“在这里输入”可以输入一个菜单名字创建一个菜单。

image-20220729102206195
1.6.2.3 添加菜单项
image-20220729102253651

在UI界面中添加菜单项只能用英文,因为此时会创建一个QAction对象,会用输入的值作为对象名,所以不能用中文,得添加后再属性窗口改中文。

image-20220729102325437
1.6.2.4 添加多级菜单
image-20220729102544754 image-20220729102601626

1.6.3 工具栏

1.6.3.1 添加/删除工具栏

删除工具栏方法和删除菜单栏方法一样,不过工具栏可以有多个,所以每次右键MainWindow对象,都可以看到添加工具栏的选项。

img
1.6.3.2 工具栏添加动作

新添加的QAction对象会在动作编辑器里找到(Action Editor),可以直接拖拽上来添加到工具栏里。

image-20220729103908393

可以对工具栏设定停靠区域、能否浮动、能否移动等

image-20220729103930777

1.6.4 状态栏

添加和删除状态栏的方法和添加删除菜单栏方法一样。

状态栏添加左侧控件、右侧控件只能通过代码来添加。

1.6.5 停靠部件

从工具箱中拖出一个停靠部件就行。也可以像设定工具栏停靠范围一样,在停靠部件的属性窗口中设定他可以停靠的范围。

image-20220729105128920

1.6.6 核心部件

UI窗口中默认核心部件就是一个widget

image-20220729105219050

1.7 UI文件原理

使用UI文件创建界面很轻松很便捷,原理就是每次我们保存UI文件的时候,QtCreator就自动帮我们将UI文件翻译成C++的图形界面创建代码。可以通过以下步骤查看代码

到工程编译目录,一般就是工程同级目录下会生成另一个编译目录,会找到一个带ui_前缀跟ui文件同名的.h文件,这就是代码

1.8 UI文件下使用信号和槽

1.8.1 转到槽

在UI编辑界面中使用信号和槽很方便,比如,拖出一个Button到窗口上,右键这个button,选择转到槽:

image-20220729105538690

此时会出现这个控件(QPushButton)可以连接的各个信号,我们可以根据具体需求选中信号来创建一个连接这个信号的槽函数:

image-20220729105623946

以click(bool)信号为例,创建了一个槽函数

image-20220729105713202

这个槽函数是QtCreator自动帮我们创建的,而且也使用生成C++代码的方式帮我们做好了连接,我们可以直接在这个函数体内实现功能就行。很方便,比使用Lambda表达式还方便。

1.8.2 信号槽编辑器

可以使用动作编辑器旁边的信号槽编辑器,里边也可以添加信号和槽的连接,比如添加actionQuit的triggered信号和窗口close槽的连接:

image-20220729105813892

1.9 资源文件

Qt 资源系统是一个跨平台的资源机制,用于将程序运行时所需要的资源以二进制的形式存储于可执行文件内部。如果你的程序需要加载特定的资源(图标、文本翻译等),那么,将其放置在资源文件中,就再也不需要担心这些文件的丢失。也就是说,如果你将资源以资源文件形式存储,它是会编译到可执行文件内部。

使用 Qt Creator 可以很方便地创建资源文件。我们可以在工程上点右键,选择“添加新文件…”,可以在 Qt 分类下找到“Qt 资源文件”:

点击“选择…”按钮,打开“新建 Qt 资源文件”对话框。在这里我们输入资源文件的名字和路径:

点击下一步,选择所需要的版本控制系统,然后直接选择完成。我们可以在 Qt Creator 的左侧文件列表中看到“资源文件”一项,也就是我们新创建的资源文件:

image-20220729105923834

右侧的编辑区有个“添加”,我们首先需要添加前缀,比如我们将前缀取名为 images。然后选中这个前缀,继续点击添加文件,可以找到我们所需添加的文件。这里,我们选择 document-open.png 文件。当我们完成操作之后,Qt Creator 应该是这样子的:

image-20220729110036004

接下来,我们还可以添加另外的前缀或者另外的文件。这取决于你的需要。当我们添加完成之后,我们可以像前面一章讲解的那样,通过使用 : 开头的路径来找到这个文件。比如,我们的前缀是 /images,文件是 document-open.png,那么就可以使用:/images/document-open.png找到这个文件。

这么做带来的一个问题是,如果以后我们要更改文件名,比如将 docuemnt-open.png 改成 docopen.png,那么,所有使用了这个名字的路径都需要修改。所以,更好的办法是,我们给这个文件去一个“别名”,以后就以这个别名来引用这个文件。具体做法是,选中这个文件,添加别名信息:

image-20220729110116558

这样,我们可以直接使用:/images/doc-open引用到这个资源,无需关心图片的真实文件名。

Qrc文件只是记录了我们要用到的资源文件在项目路径哪个位置的一个信息,如果我们使用文本编辑器打开 res.qrc 文件,就会看到以下内容:

<RCC>
    	<qresource prefix="/images">
        	<file alias="doc-open">document-open.png</file>
    	</qresource>
    	<qresource prefix="/images/fr" lang="fr">
        	<file alias="doc-open">document-open-fr.png</file>
    	</qresource>
</RCC>

当我们编译工程之后,我们可以在构建目录中找到 qrc_res.cpp 文件。

这就是 Qt 将我们的资源编译成了 C++ 代码:

image-20220729110215483

可以看出Qt帮我们将资源文件内容一个字节一个字节的读出来最终放到了代码里,使用字符数组的形式保存着,所以程序启动的时候这些资源就会以数组的形式占用到程序内存里。当我们使用qt的qrc资源文件时要考虑内存占用的问题,如果Qt程序资源很多,而且并不是每次运行程序都会加载所有的资源,比如制作一个游戏,所需要的图片声音资源量很大,可能超过了机器内存大小,这时候使用qrc加载资源的方式很不合适。

可以考虑动态加载资源的方式,当切入到某个游戏场景的时候才加载场景相关的图片声音资源。Qt有提供rcc的方式动态加载资源,不过不常用,所以一般游戏资源都放在可执行文件exe所在目录或者子目录下,程序运行的时候就从游戏exe文件路径去搜寻资源。

posted @   Happinesspill  阅读(310)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示