QWidget/QMainWindow与QLayout的布局
1.使用QWidget和QVBoxLayout 添加菜单栏和其他控件布局
demo如下:
#include <QWidget>#include <QApplication>
#include <QLayout>
#include <QToolBar>
#include <QWidgetAction>
#include <QPushButton>
#include <QLineEdit>
int main(int argc, char *argv[])
{QApplication a(argc, argv);QWidget w;w.setWindowTitle("testWidgetToolBar");QVBoxLayout *layout = new QVBoxLayout(&w);// 1. 创建 QToolBarQToolBar *toolBar = new QToolBar();// 2. 创建 QWidgetAction 并设置其 QWidget(如 QPushButton)QWidgetAction *widgetAction = new QWidgetAction(toolBar);QPushButton *button = new QPushButton("Button in QWidgetAction");widgetAction->setDefaultWidget(button);// 3. 将 QWidgetAction 添加到 QToolBartoolBar->addAction(widgetAction);// 4. 可选:添加普通 QAction(如分隔符或普通按钮)toolBar->addSeparator();toolBar->addAction("Normal Action");// 5. 将 QToolBar 添加到布局layout->addWidget(toolBar, 0, Qt::AlignTop);// 6. 可选:添加其他控件到布局QLineEdit *lineEdit = new QLineEdit();layout->addWidget(lineEdit,1, Qt::AlignTop);QLineEdit *lineEdit1 = new QLineEdit();layout->addWidget(lineEdit1);layout->setContentsMargins(10,20,40,60);w.show();return a.exec();
}
运行结果如下:
2.使用QWidget介绍QHBoxLayout、QVBoxLayout 的嵌套布局
布局可参考Qt官网QBoxLayout Class | Qt Widgets | Qt 6.9.1
QBoxLayout跟QLayout、QHBoxLayout、QVBoxLayout类之间的关系如下:
现将官网文档部分内容摘录如下:
对上面的选中的部分进行demo验证
#include <QMainWindow>
#include <QApplication>
#include <QLayout>
#include <QToolBar>
#include <QWidgetAction>
#include <QPushButton>
#include <QLineEdit>
int main(int argc, char *argv[])
{QApplication a(argc, argv);QMainWindow w;w.setWindowTitle("QMainWindow");QWidget window;window.setWindowTitle("Nested Layout Demo");// 2. 创建顶层布局(QVBoxLayout)QVBoxLayout *mainLayout = new QVBoxLayout(&window);// 3. 创建嵌套布局(QHBoxLayout)QHBoxLayout *hLayout = new QHBoxLayout();// 4. 向嵌套布局添加控件(两个按钮)QPushButton *button1 = new QPushButton("Button 1");QPushButton *button2 = new QPushButton("Button 2");hLayout->addWidget(button1);hLayout->addWidget(button2);// 5. 关键步骤:将嵌套布局添加到顶层布局mainLayout->addLayout(hLayout); // ✅ 必须先添加到父布局// 6. 向顶层布局添加其他控件(QLineEdit)QLineEdit *lineEdit = new QLineEdit();mainLayout->addWidget(lineEdit);window.show();w.show();return a.exec();
}
QMainWindow 和QWidget两个界面运行结果如下:
上面左图是正常显示,右图是折叠显示。
发现:如果将上面代码中 QWidget window的类型换成QMainWindow window;则上面添加到window中的控件内容不显示,如下:
因为QMainWindow
是一个特殊的窗口类,它内部已经预设了 中央控件(Central Widget) 和其他可停靠区域(如菜单栏、状态栏等)。如果直接对 QMainWindow
调用 setLayout()
或添加布局,可能会与它的内部结构冲突,导致布局失效。QMainWindow
要求所有内容必须放在一个 中央控件(QWidget*
)中,而布局应该设置在这个中央控件上,而不是直接设置在 QMainWindow
上。
3.使用QMainWindow
介绍QHBoxLayout、QVBoxLayout 的嵌套布局
#include "mainwindow.h"
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QWidget> // 需要包含 QWidget 头文件int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow window;window.setWindowTitle("QMainWindow Layout Demo");// 2. 创建一个中央控件(QWidget)QWidget *centralWidget = new QWidget(&window);window.setCentralWidget(centralWidget); // 必须设置中央控件// 3. 创建顶层布局(QVBoxLayout),并设置到中央控件QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);// 4. 创建嵌套布局(QHBoxLayout)QHBoxLayout *hLayout = new QHBoxLayout();// 5. 向嵌套布局添加控件(两个按钮)QPushButton *button1 = new QPushButton("Button 1");QPushButton *button2 = new QPushButton("Button 2");hLayout->addWidget(button1);hLayout->addWidget(button2);// 6. 将嵌套布局添加到顶层布局mainLayout->addLayout(hLayout);// 7. 向顶层布局添加其他控件(QLineEdit)QLineEdit *lineEdit = new QLineEdit();mainLayout->addWidget(lineEdit);window.show();return a.exec();
}
运行结果如下:
4.QMaindwow和QWidget的区别
QMaindwow的代码如下:
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>int main(int argc, char *argv[]) {QApplication app(argc, argv);QMainWindow window;window.setWindowTitle("QMainWindow Demo");// 设置中央控件QWidget *centralWidget = new QWidget(&window);window.setCentralWidget(centralWidget);QVBoxLayout *layout = new QVBoxLayout(centralWidget);layout->addWidget(new QPushButton("Button 1"));layout->addWidget(new QPushButton("Button 2"));// 添加菜单栏QMenuBar *menuBar = window.menuBar();QMenu *fileMenu = menuBar->addMenu("File");fileMenu->addAction("Open");fileMenu->addAction("Save");// 添加工具栏QToolBar *toolBar = window.addToolBar("Main Toolbar");toolBar->addAction("New");toolBar->addAction("Exit");// 调用默认状态栏显示window.statusBar()->showMessage("Ready", 2000); // 显示 2 秒(单位:毫秒)window.show();return app.exec();
}
运行结果如下:
QWidget的代码如下:
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>int main(int argc, char *argv[]) {QApplication app(argc, argv);QWidget window;window.setWindowTitle("QWidget Demo");QVBoxLayout *layout = new QVBoxLayout(&window);layout->addWidget(new QPushButton("Button 1"));layout->addWidget(new QPushButton("Button 2"));window.show();return app.exec();
}
运行结果如下:
特性 | QWidget | QMainWindow |
---|---|---|
设计目的 | 通用窗口部件 | 主应用程序窗口 |
布局管理 | 直接设置布局 | 必须通过 centralWidget 设置布局 |
内置功能 | 无额外功能 | 菜单栏、工具栏、状态栏、停靠窗口等 |
适用场景 | 简单窗口、自定义控件 | 复杂主窗口(如文本编辑器、IDE) |
代码复杂度 | 简单 | 较复杂(需管理多个组件) |