news 2026/4/2 6:58:08

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/3/13 1:57:27

如何在Java Controller中处理POST请求?

在Java Web开发中&#xff0c;处理HTTP POST请求并获取请求中的参数是一项常见任务。这通常是通过使用Servlet技术或者Spring框架来实现的。以下是两种常见框架&#xff08;Servlet和Spring MVC&#xff09;中处理POST请求参数的方法。 1. 使用Servlet如果你正在使用Servlet AP…

作者头像 李华
网站建设 2026/4/1 15:10:48

解锁触手可及的温暖:网易智企 x Wander Puffs AI 云游泡芙

Raingo、Bo与Mimi是生活在云栖之境的三位云游泡芙。话搭子Raingo读懂你的孤独&#xff0c;慢性子Bo稳住你的焦虑&#xff0c;开心果Mimi点亮你的自信。由上海零陆零贰数字科技有限公司&#xff08;以下简称“零陆零贰”&#xff09;出品的AIIP治愈系情感陪伴玩偶“Wander Puffs…

作者头像 李华
网站建设 2026/4/3 3:54:12

PHP在网页中如何实现视频大文件的秒传与切片分享?

重庆老码农的「百元预算大文件传输」解决方案 一、项目开场白 各位同行好&#xff01;老张我今年45岁&#xff0c;头发都快掉光了还在写代码。最近接了个「20G文件夹上传」的活儿&#xff0c;客户要求用原生JSPHP实现&#xff0c;预算100块还要7*24小时支持…&#xff08;掏出…

作者头像 李华
网站建设 2026/3/16 10:12:41

做了10000套板子,部分 LED 异常,太细节了。

近期&#xff0c;某工程师反馈他们生产的一批10000套板子中&#xff0c;出现了上百套LED工作异常的情况。具体表现为&#xff1a;板卡上有3个LED指示灯&#xff0c;正常上电后应全部点亮&#xff0c;但异常板子会随机出现某个LED不亮&#xff0c;而板子上的其他功能均正常。下图…

作者头像 李华
网站建设 2026/4/3 4:29:35

第2章Java基本语法(上): 变量与运算符--标识符 变量

2.2 标识符(Identifier)标识符&#xff1a; Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符 技巧&#xff1a;凡是自己可以起名字的地方都叫标识符。 定义合法标识符规则&#xff1a; 由26个英文字母大小写&#xff0c;0-9 &#xff0c;_或 $ 组成 …

作者头像 李华