news 2026/9/1 4:40:34

Qt 主窗口开发三件套:菜单栏、工具栏、状态栏与停靠窗口实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qt 主窗口开发三件套:菜单栏、工具栏、状态栏与停靠窗口实战

Qt 主窗口开发三件套:菜单栏、工具栏、状态栏与停靠窗口实战

  • Qt 主窗口开发三件套:菜单栏、工具栏、状态栏与停靠窗口实战
    • 前言
    • 1. 为什么 Qt 很适合做传统桌面程序
    • 2. QMenuBar:菜单栏是主窗口的骨架
      • 2.1 给菜单设置快捷方式
      • 2.2 给action(动作)设置快捷方式
      • 2.3 设置子菜单
      • 2.4 在菜单中给每个菜单项添加分隔线
    • 3. QAction:菜单项和工具栏按钮的共同抽象
    • 4. QToolBar:把高频操作提到最前面
    • 5. QStatusBar:轻量反馈特别好用
    • 6. QDockWidget:让界面更像 IDE
    • 7. 这几块组件之间怎么协作
    • 8. 一个简化版主窗口思路
    • 9. 我在这组练习里的体会
      • 9.1 主窗口不是“多几个控件”,而是结构升级
      • 9.2 QAction 这个抽象特别值钱
      • 9.3 桌面程序的味道,很多时候就来自这些细节
    • 10. 总结

Qt 主窗口开发三件套:菜单栏、工具栏、状态栏与停靠窗口实战

前言

很多人第一次接触 Qt,最先看到的是按钮、标签、输入框这些基础控件。但如果真的想做一个“像样的桌面程序”,光会摆控件还不够,真正能把桌面软件气质拉起来的,其实是主窗口这一整套东西。
比如:

  • 顶部的菜单栏
  • 常用操作放到工具栏
  • 底部的状态栏
  • 可以拖来拖去的停靠窗口

这些东西组合起来,才会让一个程序看起来像编辑器、像管理工具、像真正的桌面应用。

我这篇文章,就结合自己的一些经验,把 Qt 主窗口里最常用的几块讲清楚。

1. 为什么 Qt 很适合做传统桌面程序

Qt 有一个很明显的特点:它对桌面程序那种“菜单 + 工具栏 + 状态栏 + 子面板”的结构支持得特别完整。

如果你只是做一个很小的弹窗程序,这些能力不一定重要。
但如果你想做:

  • 配置工具
  • 文件管理器
  • 数据录入界面
  • IDE 风格的小工具

那主窗口体系就会很有价值。

在 Qt 里,这些能力大多都围绕QMainWindow展开。相比普通的QWidgetQMainWindow天生就更适合承载复杂界面。

2. QMenuBar:菜单栏是主窗口的骨架

菜单栏通常是主窗口最显眼的结构之一,像一些主流的IDE,比如VScode都会有自己的菜单栏:

在 Qt 里,我们可以先拿到主窗口自己的菜单栏,再往里面加菜单:

QMenuBar*menubar=this->menuBar();this->setMenuBar(menubar);QMenu*menu=newQMenu("文件");menubar->addMenu(menu);

这一步其实在做两件事:

  1. 建立主窗口最上方的菜单容器
  2. 把功能按“文件、编辑、视图”这种思路组织起来

我自己练这组例子的时候,一个很明显的感受是:
菜单栏不是为了好看,而是为了把功能分组。

如果一个程序功能一多,没有菜单栏的话,用户会很快找不到入口。

运行结果:

2.1 给菜单设置快捷方式

菜单栏是必须有菜单的,否则就没有意义。

但是有时候我们希望给有一些高频使用的菜单,比如文件,设置快捷方式,Qt中支持下面的方式:

// 创建菜单 QMenu* menu1 = new QMenu("文件 (&F)"); QMenu* menu2 = new QMenu("编辑 (&E)"); QMenu* menu3 = new QMenu("构建 (&B)");

&F就是将对应的菜单和大写字母绑定在了一起,当我们按那个大写字母时,等同于按下了那个菜单键。

2.2 给action(动作)设置快捷方式

我们不仅可以给菜单设置快捷方式,还可以给动作设置:

QAction* action1 = new QAction("打开 (&A)"); QAction* action2 = new QAction("关闭 (&C)"); QAction* action3 = new QAction("查看 (&G)");

运行结果:

我们先按快捷方式F打开菜单文件,再按快捷方式A就能触发action1的动作。

2.3 设置子菜单

在Qt中也支持给某一个菜单设置子菜单:

QMenuBar* menuBar = new QMenuBar(); this->setMenuBar(menuBar); QMenu* menuParent = new QMenu("父菜单"); QMenu* menuChild = new QMenu("子菜单"); menuBar->addMenu(menuParent); menuParent->addMenu(menuChild);

运行结果:

2.4 在菜单中给每个菜单项添加分隔线

有时候,某个菜单的菜单项太多了,用来把一组菜单项和另一组菜单项视觉上隔开,让菜单结构更清晰。

menu->addSeparator()

运行结果:

3. QAction:菜单项和工具栏按钮的共同抽象

Qt 里有个特别值得注意的类,叫QAction

你可以把它理解成“一个动作”,而不是“一个按钮”。

例如:

QAction*action1=newQAction("保存");QAction*action2=newQAction("打开");

这两个动作既可以加进菜单:

menu->addAction(action1);menu->addAction(action2);

也可以加进工具栏:

toolbar->addAction(action1);toolbar->addAction(action2);

这就是 Qt 很优雅的一点:
菜单和工具栏虽然长得不一样,但背后操作的其实是同一个动作对象,这相当于一个功能在不同的地方的复用,可以节省资源。

这样做的好处是:

  • 逻辑统一
  • 状态统一
  • 不容易重复写代码

4. QToolBar:把高频操作提到最前面

菜单适合分组,工具栏适合高频操作。

比如保存、打开、刷新,这些动作如果每次都要走菜单,效率会低很多。放到工具栏上,用户一眼就能点到。

我现在这个QToolBar示例里,核心结构就是:

QToolBar*toolbar=newQToolBar();this->addToolBar(toolbar);QAction*action1=newQAction("保存");QAction*action2=newQAction("打开");action1->setIcon(QIcon(":/save.png"));action2->setIcon(QIcon(":/open.png"));toolbar->addAction(action1);toolbar->addAction(action2);

然后再把动作连到槽函数:

connect(action1,&QAction::triggered,this,&MainWindow::handle1);connect(action2,&QAction::triggered,this,&MainWindow::handle2);

这一步特别适合写进博客,因为它能很清楚地体现:

  • QAction是行为
  • QToolBar是行为的可视化载体
  • 图标和 tooltip 则是在帮用户快速识别行为,可以给动作添加图标属性,便于用户辨别。

运行结果:

5. QStatusBar:轻量反馈特别好用

状态栏很容易被忽略,但它其实是桌面应用里特别实用的一块。

比如:

  • 提示“保存成功”
  • 展示当前状态
  • 放一个进度条
  • 放一些小标签

在 Qt 里拿到状态栏非常直接:

QStatusBar*statusbar=this->statusBar();this->setStatusBar(statusbar);

然后可以往里加控件:

QLabel*label=newQLabel("这是一个label");statusbar->addWidget(label);QProgressBar*progressbar=newQProgressBar();progressbar->setRange(0,100);progressbar->setValue(50);statusbar->addWidget(progressbar);

我自己挺喜欢状态栏的原因是,它非常适合放“轻提示”。
比起每次都弹对话框,状态栏的反馈更轻,不打断用户流程,能让用户的体验很好。

运行结果:

6. QDockWidget:让界面更像 IDE

如果说菜单栏、工具栏、状态栏已经能让程序像个桌面软件了,那QDockWidget会让它更像一个“专业桌面工具”。

它最大的特点是:
可以作为可停靠、可拖动的子面板存在。

比如:

QDockWidget*dock=newQDockWidget();this->addDockWidget(Qt::LeftDockWidgetArea,dock);// 设置初始的停靠区域QWidget*widget=newQWidget();dock->setWidget(widget);

再往里面放布局和控件:

QVBoxLayout*vbox=newQVBoxLayout();widget->setLayout(vbox);QPushButton*button1=newQPushButton("按钮1");QPushButton*button2=newQPushButton("按钮2");vbox->addWidget(button1);vbox->addWidget(button2);

这时候你就已经有一个“可挂载的边栏面板”了。

它特别适合做:

  • 工具面板
  • 属性面板
  • 日志窗口
  • 辅助导航区域

很多编辑器类软件之所以看起来很专业,很大一部分原因就是它们把主界面拆成了主工作区 + 若干停靠面板。

运行结果:

还可以设置允许停靠的区域:

dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::TopDockWidgetArea);

7. 这几块组件之间怎么协作

当我把这些小工程连起来看时,我越来越觉得 Qt 主窗口的设计非常像一套分工明确的体系:

  • QMenuBar:负责分类入口
  • QAction:负责动作抽象
  • QToolBar:负责高频快捷入口
  • QStatusBar:负责轻量反馈
  • QDockWidget:负责附属工作区

你会发现,它们并不是孤立的控件,而更像一个“桌面程序骨架”。

如果你的程序只是单页面按钮堆砌,用户会觉得它像个 demo。
但一旦这几块配合起来,程序的完成度和专业感会明显提高。

8. 一个简化版主窗口思路

如果让我用现在这些练习工程拼一个小型桌面工具,我会这样组织:

  • 顶部菜单栏:文件、编辑、视图、帮助
  • 工具栏:保存、打开、刷新
  • 中间主区域:实际业务界面
  • 左边停靠窗口:导航或工具面板
  • 底部状态栏:显示提示和进度

这样其实已经很像一个真正的桌面应用框架了。

哪怕业务逻辑还不复杂,界面结构先搭对,后面扩展起来也会顺很多。

9. 我在这组练习里的体会

9.1 主窗口不是“多几个控件”,而是结构升级

普通控件更多是在填充内容,主窗口组件更像是在组织内容。

它们决定的是“界面怎么分层、功能怎么分组、反馈怎么展示”。

9.2 QAction 这个抽象特别值钱

我一开始并没有很重视QAction,后来才发现它是把菜单和工具栏统一起来的关键。

这也是 Qt 设计里我挺喜欢的一点:它不是把 UI 元素硬堆在一起,而是先抽象动作,再决定动作怎么显示。

9.3 桌面程序的味道,很多时候就来自这些细节

一个工具栏图标、一个状态栏提示、一个可停靠面板,单独看都不算大功能。
但它们放在一起,用户就会感觉这个程序更像“产品”,而不只是“练习工程”。

10. 总结

如果把 Qt 主窗口最核心的几块抽出来,我觉得可以记成一句话:

菜单栏负责分组,工具栏负责快捷,状态栏负责反馈,停靠窗口负责扩展。

这四块一旦配合起来,QMainWindow的价值就出来了。

而且它们都不是只适合大项目。哪怕你现在只是做课程练习,只要有意识地把这些结构练熟,后面真写稍微复杂一点的桌面工具时,就会轻松很多。

对我来说,这组练习最大的收获不是“我会用了几个 Qt 类”,而是我开始理解:
一个桌面程序的界面,不只是控件堆出来的,更是结构设计出来的。

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

AI辅助Python爬虫实战:SeepSeek高效采集京东商品数据

这次我们来看一个用 Python 和 SeepSeek 搞定京东商品数据采集的实战项目。这个项目的核心不是讲复杂的爬虫原理,而是直接告诉你,如何利用 AI 工具(SeepSeek)来高效、稳定地完成一个价值 1500 元的京东数据采集单子。即使你是 Pyt…

作者头像 李华
网站建设 2026/9/1 4:40:11

普元获评低/零代码市场典型供应商,融合智能化能力推进复杂场景

在最近的日子里, 有一份名为《: 中国低代码/零代码市场发展洞察 (2023)》的报告, 它是由低代码领域里具备权威地位的研究机构, 联合行业当中重点的厂商, 正式予以发布, 并且还进行了详细的解读。普元身为智能低代码开发平台方面处于领先位置的厂商, 被选入了这份报告, 还被评定…

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

LLM应用开发:基于Anansi构建结构化记忆API实现智能对话助手

在实际 LLM 应用开发中,一个常被忽视但至关重要的组件是“记忆”系统。无论是构建一个能记住对话历史的聊天机器人,还是一个能根据用户历史行为提供个性化建议的智能助手,都需要一个可靠、高效且可扩展的机制来存储、检索和关联上下文信息。直…

作者头像 李华
网站建设 2026/9/1 4:37:42

VITS-Fast-Fine-Tuning数据准备全攻略:从录音到可训练样例

简介:本资源是专为VITS语音合成模型快速微调实践设计的开箱即用型样例数据包,面向语音合成初学者、AI开发者及需要定制化TTS能力的技术人员,解决从零配置环境、准备数据到启动训练的入门门槛问题。压缩包共983个文件,主体为979段高…

作者头像 李华
网站建设 2026/9/1 4:35:05

TBR 架构下全屏 Resolve 的必要性解析

开场 上个月给移动端项目做后处理优化,跑 Profile 时发现一个诡异的现象:后处理 Pass 明明只采样了一张全屏纹理,GPU 却把整个 framebuffer 重新 flush 到主内存,带宽直接飙到 800MB/s,功耗也跟着起飞。 起初以为是 RenderTexture 格式选错了,换成 R16G16B16A16 也没用…

作者头像 李华
网站建设 2026/9/1 4:30:22

C# WinForms集成OCR引擎实战:从图片到文字的识别方案

简介:面向C#开发者的OCR通用识别Demo,基于PaddleOCR模型封装,解决在.NET环境下快速接入图像文字识别能力的问题,可应用于截图取词、合同票据识别、PDF文档文字提取等场景。项目整合图形处理库Clipper、Emgu.CV完成图像预处理&…

作者头像 李华