news 2026/6/15 21:12:15

QT——QMainWindow

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
QT——QMainWindow

目录

QMainWindow

菜单栏(Menu Bar)

添加菜单栏,添加菜单,添加菜单项,并为菜单项设置触发事件(槽函数)

给菜单,菜单项添加快捷键

添加子菜单

给菜单项之间添加分割线

给菜单/菜单项添加图标

题外话——创建菜单栏的内存泄漏

工具栏(QToolBar)

创建工具栏,给工具栏添加action,给action设置图标以及提示信息

菜单栏和工具栏结合使用

设置多个工具栏

工具栏的移动设置

状态栏(Status Bar)

QDockWidget


QMainWindow

大多数时候客户端窗口的主体是QMainWindow而不是QWidget,QWidget是其中的组成部分。QMainWindow的组成如下:

实际上,当我们创建一个QMainWindow项目并选择生成ui文件的时候,中心窗口,菜单栏,状态栏都是默认创建好的:


菜单栏(Menu Bar)

一个窗口只能有一个菜单栏,菜单栏结构示意图如下:

添加菜单栏,添加菜单,添加菜单项,并为菜单项设置触发事件(槽函数)

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建一个菜单栏对象 QMenuBar* menubar = new QMenuBar(); //将菜单栏添加到窗口,此时menubar的父节点被设置为窗口 this->setMenuBar(menubar); //给菜单栏添加菜单 QMenu *menu1 = new QMenu("文件");//创建菜单对象 QMenu *menu2 = new QMenu("编辑"); QMenu *menu3 = new QMenu("帮助"); menubar->addMenu(menu1);//把菜单对象添加到菜单栏 menubar->addMenu(menu2); menubar->addMenu(menu3); //给菜单添加菜单项 QAction * action1 = new QAction("打开");//创建菜单项对象 QAction * action2 = new QAction("保存"); QAction * action3 = new QAction("退出"); menu1->addAction(action1);//把菜单项对象添加到菜单 menu1->addAction(action2); menu1->addAction(action3); //给菜单项关联一个槽 connect(action1,&QAction::triggered,this,&MainWindow::handler); } void MainWindow::handler() { qDebug()<<"点击了打开按钮!"; }

给菜单,菜单项添加快捷键

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建一个菜单栏对象 QMenuBar* menubar = new QMenuBar(); //将菜单栏添加到窗口,此时menubar的父节点被设置为窗口 this->setMenuBar(menubar); //给菜单栏添加菜单 QMenu *menu1 = new QMenu("文件(&a)");//创建菜单对象,并添加快捷键ALt+a QMenu *menu2 = new QMenu("编辑(&b)"); QMenu *menu3 = new QMenu("帮助(&c)"); menubar->addMenu(menu1);//把菜单对象添加到菜单栏 menubar->addMenu(menu2); menubar->addMenu(menu3); //给菜单添加菜单项 QAction * action1 = new QAction("打开(&z)");//创建菜单项对象并添加快捷键ALt+z QAction * action2 = new QAction("保存"); QAction * action3 = new QAction("退出"); menu1->addAction(action1);//把菜单项对象添加到菜单 menu1->addAction(action2); menu1->addAction(action3); //给菜单项关联一个槽 connect(action1,&QAction::triggered,this,&MainWindow::handler); }

在菜单/菜单项文本添加"&+字母"就表示给这个菜单/菜单项添加快捷键"alt+字母"

添加子菜单

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建一个菜单栏对象 QMenuBar* menubar = new QMenuBar(); //将菜单栏添加到窗口,此时menubar的父节点被设置为窗口 this->setMenuBar(menubar); //给菜单栏添加菜单 QMenu *menu1 = new QMenu("父菜单");//创建菜单对象 QMenu *menu2 = new QMenu("菜单2"); QMenu *menu3 = new QMenu("子菜单"); menubar->addMenu(menu1);//把菜单对象添加到菜单栏 menubar->addMenu(menu2); menu1->addMenu(menu3);//菜单对象中也有addMenu方法,用于添加子菜单 //给菜单添加菜单项 QAction * action1 = new QAction("打开");//创建菜单项对象 QAction * action2 = new QAction("保存"); QAction * action3 = new QAction("退出"); menu1->addAction(action1);//把菜单项对象添加到菜单 menu3->addAction(action2); menu3->addAction(action3); }

给菜单项之间添加分割线

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建一个菜单栏对象 QMenuBar* menubar = new QMenuBar(); //将菜单栏添加到窗口,此时menubar的父节点被设置为窗口 this->setMenuBar(menubar); //给菜单栏添加菜单 QMenu *menu1 = new QMenu("菜单1");//创建菜单对象 QMenu *menu2 = new QMenu("菜单2"); menubar->addMenu(menu1);//把菜单对象添加到菜单栏 menubar->addMenu(menu2); //给菜单添加菜单项 QAction * action1 = new QAction("菜单项1");//创建菜单项对象 QAction * action2 = new QAction("菜单项2"); QAction * action3 = new QAction("菜单项3"); QAction * action4 = new QAction("菜单项4"); menu1->addAction(action1);//把菜单项对象添加到菜单 menu1->addAction(action2); menu1->addSeparator();//把分割线也当做一个菜单项,它在谁后面被添加,分割线就在谁后面 menu1->addAction(action3); menu1->addAction(action4); }

给菜单/菜单项添加图标

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建一个菜单栏对象 QMenuBar* menubar = new QMenuBar(); //将菜单栏添加到窗口,此时menubar的父节点被设置为窗口 this->setMenuBar(menubar); //给菜单栏添加菜单 QMenu *menu1 = new QMenu("菜单1");//创建菜单对象 QMenu *menu2 = new QMenu("子菜单");//创建菜单对象 menubar->addMenu(menu1);//把菜单对象添加到菜单栏 menu1->addMenu(menu2);//给菜单1添加子菜单 //给菜单1添加图标 menu1->setIcon(QIcon(":/rose.jpg")); //给子菜单添加图标 menu2->setIcon(QIcon(":/rose.jpg")); //给菜单添加菜单项 QAction * action1 = new QAction("菜单项1");//创建菜单项对象 //给菜单项添加图标 action1->setIcon(QIcon(":/rose.jpg")); //把菜单项对象添加到菜单 menu1->addAction(action1); }

菜单,子菜单,菜单项都可以设置图标,但是如果给菜单设置图标的话,就会把原有文本覆盖

题外话——创建菜单栏的内存泄漏

在该文章开头我们以及谈及,一旦创建了一个QMainWindows项目并且选择使用QtDesigner(也就是使用ui文件),那么默认就会生成一个菜单栏,而上面的所有代码中我是这么写的:

//创建一个菜单栏对象 QMenuBar* menubar = new QMenuBar(); //将菜单栏添加到窗口,此时menubar的父节点被设置为窗口 this->setMenuBar(menubar);

一个窗口只能有一个菜单栏,这就相当于我们新创建了一个菜单栏,把人家默认生成的给替换掉了,原有的菜单栏对象就得不到释放了。(细心的同学可能发现我在创建菜单栏的时候没有指定菜单栏的父对象可能导致内存泄漏,不必担心,setMenuBar会帮我们把对象挂到对象树上。)下面我们修改代码,修复内存泄漏:

QMenuBar* menubar = this->menuBar(); this->setMenuBar(menubar);

menuBar函数就是从窗口中获取一个菜单栏对象,如果有就直接获取,如果没有就创建一个。这样一来,在下面设置窗口的菜单栏时,如果本来没有,我们就把新创建的菜单栏对象设置进去了,如果有,也是自己替换自己,不会造成内存泄漏。

当然,不只是菜单栏,选择ui文件后默认生成的栏如果使用不当都会出现这种问题。


工具栏(QToolBar)

大多数情况下,工具栏中的内容就是菜单中的菜单项,相当于菜单项的快捷键,因此工具栏中的元素也是用QAction对象表示

除此之外,一个窗口可以有多个工具栏,也正是因此,添加工具栏的接口是addToolBar而不是像添加菜单栏一样格式的setToolBar。

建工具栏,给工具栏添加action,给action设置图标以及提示信息

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建工具栏对象 QToolBar* tb = new QToolBar(); //将工具栏对象添加到窗口中 this->addToolBar(tb); //创建QAction QAction * action1 = new QAction("选项1"); QAction * action2 = new QAction("选项2"); //给QAction设置图标,一般来说工具栏的元素都用图标表示 action1->setIcon(QIcon(":/rose.jpg")); action2->setIcon(QIcon(":/rose.jpg")); //给工具栏上的元素设置图标会导致文本被覆盖,因此可以给每个元素设置一个提示信息,鼠标悬停到对应元素就显示提示信息 //实际上就算不设置提示信息,也有默认的提示信息,即action原来的文本 action1->setToolTip("这是选项1"); action2->setToolTip("这是选项2"); //把QAction对象添加到工具栏中 tb->addAction(action1); tb->addAction(action2); }

菜单栏和工具栏结合使用

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建工具栏对象 QToolBar* tb = new QToolBar(); this->addToolBar(tb); //添加菜单栏对象 QMenuBar* mb = this->menuBar(); this->setMenuBar(mb); //创建QAction QAction * action1 = new QAction("选项1"); QAction * action2 = new QAction("选项2"); //把QAction对象添加到工具栏中 tb->addAction(action1); tb->addAction(action2); //把QAction对象添加到菜单栏中 mb->addAction(action1); mb->addAction(action2); }

同一个action元素被菜单栏和工具栏同时包含,那么会不会导致对象树上一个节点有两个父节点?或者一个节点释放两次呢?不会的,Qt帮我们处理好了。

设置多个工具栏

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //添加工具栏对象 QToolBar* tb = new QToolBar(); this->addToolBar(tb); QToolBar* tb2 = new QToolBar(); this->addToolBar(tb); //创建QAction QAction * action1 = new QAction("选项1"); QAction * action2 = new QAction("选项2"); //把QAction对象添加到工具栏中 tb->addAction(action1); tb->addAction(action2); tb2->addAction(action1); tb2->addAction(action2); }

工具栏的移动设置

默认情况下可以将工具栏拖动到上下左右四个方向并停靠在窗口边沿,以及浮动在窗口内部

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //添加工具栏对象 QToolBar* tb = new QToolBar(); this->addToolBar(Qt::LeftToolBarArea,tb);//在添加工具栏的时候可以设置工具栏的初始位置 //创建QAction QAction * action1 = new QAction("选项1"); QAction * action2 = new QAction("选项2"); //把QAction对象添加到工具栏中 tb->addAction(action1); tb->addAction(action2); //设置工具栏只允许在左边和右边停靠以及浮动 tb->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea); //设置工具栏不允许浮动 tb->setFloatable(false); //设置工具栏不允许移动, 固定住了 tb->setMovable(false); }


状态栏(Status Bar)

状态栏也是勾选ui文件后默认生成的,设置状态栏的时候要注意内存泄漏。

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //添加状态栏对象 QStatusBar * sb = this->statusBar(); this->setStatusBar(sb); //直接让状态栏展示文本,可以timeout,到期自动不在显示文本,如果timeout为0表示一直展示 //sb->showMessage("这是一个状态消息",1000); //给状态栏添加标签控件,可以在添加的时候设置拉升系数 QLabel* label1 = new QLabel("哈哈哈"); sb->addWidget(label1,1); QLabel* label2 = new QLabel("嘿嘿嘿"); sb->addWidget(label2,2); //给状态栏添加按钮控件,这次我们从右往左添加 QPushButton* button = new QPushButton("按钮"); sb->addPermanentWidget(button);//调用这个函数就表示从右往左添加 //给状态栏添加进度条 QProgressBar* p = new QProgressBar(); p->setRange(0,100); p->setValue(50); sb->addWidget(p); }

QDockWidget

QDockWidget是一个浮动窗口控件,相当于独立的新窗口。不过需要注意的是,QDockWidget默认只能添加一个控件,因此如果想要在浮动窗口上设置更多样式需要先创建一个QWidget并把控件设置其中,然后只要把QWidget对象设置到QDockWidget中去即可

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //添加一个浮动窗口对象 QDockWidget* widget = new QDockWidget(); this->addDockWidget(Qt::LeftDockWidgetArea,widget);//添加的时候要指定新窗口的初始停靠位置 //给浮动窗口设置窗口标题 widget->setWindowTitle("浮动窗口"); //创建一个窗口对象 QWidget* qwidget = new QWidget(); //把QWidget对象设置进浮动窗口去 widget->setWidget(qwidget); //然后我们就可以在Qwidget中添加更多控件了 //创建一个布局管理器并添加到QWidget中去 QVBoxLayout* layout = new QVBoxLayout(); qwidget->setLayout(layout); //在布局管理器中添加控件 layout->addWidget(new QLabel("这是一个标签")); layout->addWidget(new QPushButton("按钮")); //还可以给浮动窗口设置什么位置可以停靠 widget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::TopDockWidgetArea); }


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 13:01:53

毕业设计项目 基于深度学的图像修复 图像补全

1 前言 Hi&#xff0c;大家好&#xff0c;这里是丹成学长&#xff0c;今天向大家介绍 基于深度学的图像修复 图像补全 大家可用于 毕业设计 &#x1f9ff; 选题指导, 项目分享&#xff1a;见文末 2 什么是图像内容填充修复 内容识别填充(译注: Content-aware fill ,是 photosho…

作者头像 李华
网站建设 2026/6/15 13:23:15

【2026】 LLM 大模型系统学习指南 (51)

机器学习模型的可解释性&#xff08;上&#xff09;&#xff1a;打开 AI 黑盒的入门指南机器学习模型常被称作 “黑盒”—— 输入数据就能得到结果&#xff0c;但背后 “为什么这么判断” 却无从知晓。而可解释性机器学习&#xff08;Explainable ML, XAI&#xff09; 的核心&a…

作者头像 李华
网站建设 2026/6/15 20:12:07

基于改进粒子群算法的园区综合能源优化调度:电动汽车的新舞台

MATLAB代码&#xff1a;基于改进粒子群算法的含电动汽车参与园区综合能源优化调度 关键词&#xff1a;电动汽车 改进粒子群 综合能源 优化调度 园区 参考文档&#xff1a;《含电动汽车的区域综合能源系统优化调度研究》第3章&#xff1a;复现 仿真平台&#xff1a;MATLAB 主要…

作者头像 李华
网站建设 2026/6/15 13:40:16

别再瞎找了!本科生专属AI论文软件 —— 千笔·专业论文写作工具

你是否曾为论文选题发愁&#xff0c;绞尽脑汁却找不到方向&#xff1f;是否在深夜面对空白文档&#xff0c;大脑一片空白&#xff0c;无从下笔&#xff1f;又或者反复修改却总对表达不满意&#xff0c;查重率居高不下&#xff1f;这些困扰&#xff0c;是无数本科生在论文写作路…

作者头像 李华
网站建设 2026/6/15 14:39:30

亲测好用 8个降AI率软件降AIGC网站:本科生降AI率全维度测评与推荐

在当前高校论文写作日益依赖AI辅助的背景下&#xff0c;如何有效降低AIGC率、去除AI痕迹&#xff0c;同时保持论文的逻辑性和语义通顺&#xff0c;成为许多本科生面临的重要课题。随着AI生成内容检测技术的不断升级&#xff0c;传统的写作方式已难以满足查重和原创性的双重要求…

作者头像 李华