QMainWindow布局框架折腾记录

发布时间:2026/5/19 21:48:31

QMainWindow布局框架折腾记录 QMainWindow 这套布局框架我折腾了两天才搞明白最近在学 Qt 的窗口系统之前几章一直用 QWidget 当主窗口写着写着发现不对劲——菜单栏、工具栏、状态栏全得自己用布局拼太蠢了。翻了下文档才知道 Qt 有个 QMainWindow专门干这事的。但说实话刚上手的时候踩了不少坑记录一下。先说 QMainWindow 的结构QMainWindow 把一个窗口分成了固定的几块区域最上面是菜单栏QMenuBar菜单栏下面可以放工具栏QToolBar而且能放好几条中间是核心工作区Central Widget这个必须设置最下面是状态栏QStatusBar左右两边可以停靠浮动窗口QDockWidget我一开始以为 QMainWindow 和 QWidget 差不多直接往里面 addLayout 就行。结果发现它根本不让你这么干——你必须用setCentralWidget()设置中央控件其他区域用专门的 API 添加。菜单栏这块菜单栏的层级关系是QMenuBar → QMenu → QAction。QMenuBar*mbmenuBar();// QMainWindow 自带的不用 newQMenu*fileMenumb-addMenu(文件(F));QAction*actOpenfileMenu-addAction(打开(O));QAction*actSavefileMenu-addAction(保存(S));fileMenu-addSeparator();// 加条分隔线QAction*actQuitfileMenu-addAction(退出(Q));这里有个细节F这种写法是设置快捷键下划线的按 AltF 就能打开文件菜单。我之前一直不知道这个语法。然后 QAction 被点击时会发出triggered()信号连接到槽函数就行connect(actOpen,QAction::triggered,this,MainWindow::onOpen);一个 QAction 可以同时加到菜单和工具栏里这点设计得挺好的——同一个动作不用写两遍。工具栏QToolBar*toolbaraddToolBar(主工具栏);toolbar-addAction(actOpen);// 直接复用菜单里的 QActiontoolbar-addAction(actSave);toolbar-setAllowedAreas(Qt::TopToolBarArea|Qt::BottomToolBarArea);setAllowedAreas可以限制工具栏只能停靠在哪些边。不设置的话用户可以把它拖到任意一边有时候会很奇怪。状态栏状态栏是最简单的一块statusBar()-showMessage(已保存,3000);// 显示 3 秒后自动消失第二个参数是毫秒数传 0 或者不传就一直显示。我手贱试了一下传负数结果也是一直显示不会报错。浮动窗口Dock Widget这个东西我觉得挺实用的类似 VS Code 左边的文件树面板那种效果QDockWidget*docknewQDockWidget(文件列表,this);dock-setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);QListWidget*listnewQListWidget(dock);list-addItems({main.cpp,mainwindow.h,mainwindow.cpp});dock-setWidget(list);addDockWidget(Qt::LeftDockWidgetArea,dock);用户可以拖动 dock 到允许的区域也可以把它拖出来变成独立浮动窗口。关闭后想再显示得通过菜单里的 action 来控制QDockWidget 自带一个 toggleViewAction。对话框踩坑Qt 内置了好几种对话框都是静态方法一行调用挺方便的。但有些地方不注意会出问题。QFileDialogQString pathQFileDialog::getOpenFileName(this,打开文件,,文本文件 (*.txt);;所有文件 (*));// 注意是两个分号 ;;我第一次写的时候用逗号分隔过滤器结果过滤器显示成一整坨字符串找了半天才发现要用;;。QMessageBoxautoretQMessageBox::question(this,确认,要保存吗,QMessageBox::Yes|QMessageBox::No);if(retQMessageBox::Yes){// 保存逻辑}QColorDialog 和 QFontDialog// 选颜色QColor colorQColorDialog::getColor(Qt::black,this,选颜色);if(color.isValid()){editor-setTextColor(color);}// 选字体boolok;QFont fontQFontDialog::getFont(ok,editor-font(),this);if(ok)editor-setFont(font);这俩都是返回值 bool 判断的模式。颜色用isValid()判断用户是否点了取消字体用传入的bool*参数。风格不统一但习惯就好。模态和非模态这个概念之前没接触过模态exec()弹出对话框后父窗口不能操作必须先关掉对话框非模态show()对话框和父窗口可以同时操作上面那些getOpenFileName、getColor之类的静态方法内部都是模态的。如果要非模态得自己 new 一个 QDialog 然后 show()QDialog*dlgnewQDialog(this);dlg-setAttribute(Qt::WA_DeleteOnClose);// 关闭时自动 delete不然内存泄漏dlg-show();WA_DeleteOnClose这个属性很重要不设的话每次 show 都 new 一个关了也不释放内存就慢慢涨上去了。最后写了个简易文本编辑器把这些东西串起来练了一遍菜单栏打开/保存文件工具栏快捷操作状态栏显示反馈dock 放个文件列表。

相关新闻