纯代码写 UI 的优点1. 工程更干净无冗余文件没有.ui界面文件、没有 uic 编译器自动生成的ui_xxx.h中间代码整个项目只有.h和.cpp版本管理Git更清爽不会出现 UI 文件 XML 冲突多人协作时几乎不会出现 UI 文件合并冲突拖拽界面经常出现乱码、布局错乱的合并问题纯代码完全规避。2. 高度可控界面逻辑一体化界面创建、参数设置、信号绑定直接写在构造函数里界面和业务代码放在一起不用来回切换 UI 设计器和代码可以动态生成界面根据配置文件、网络数据、用户权限在运行时动态创建 / 销毁 / 增删控件。拖拽 UI 只能写死固定界面运行时想批量生成几十个按钮、表格列只能靠代码纯代码写法天然适配动态界面。3. 编译更快减少头文件依赖配合前置声明class QPushButton;头文件不需要引入一大堆控件头减少头文件嵌套大型项目编译速度提升明显不会因为包含过多 UI 头文件造成循环包含问题。4. 便于封装与复用可以把一组控件 布局封装成一个自定义控件类写成独立组件在多个窗口直接 new 调用纯代码组件移植性极强复制类文件就能复用不用连带复制 ui 文件。5. 方便版本回滚与代码审查所有界面改动都是 C 代码改动Git 可以清晰看到哪一行新增了按钮、修改了布局间距、调整了控件大小拖拽 UI 保存的是 XML 文本布局微小改动都会造成整段 XML 变动很难看清改了什么。6. 更容易实现精细化自定义如果要自己重写paintEvent绘制控件、自定义鼠标交互、做异形窗口、动画切换界面纯代码连贯开发更顺畅不用在设计师里摆放控件再去写自定义逻辑前后代码无缝衔接。7. 跨平台部署更省心少了 uic 编译环节编译链路更简单在 Linux、嵌入式 Qt 环境下交叉编译时少一个编译步骤不容易出编译环境问题。缺点这里暂不讨论main.cpp:#include QApplication #include mainwindow.h int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }mainwindow.h#ifndef MAINWINDOW_H #define MAINWINDOW_H #include QWidget class QPushButton; class QLabel; class QLineEdit; class QTextEdit; class QPlainTextEdit; class QCheckBox; class QRadioButton; class QComboBox; class QSlider; class QTableWidget; class QTreeWidget; class MainWindow : public QWidget { Q_OBJECT public: explicit MainWindow(QWidget *parent nullptr); private: QPushButton* m_btn; QLabel* m_label; QLineEdit* m_lineEdit; QTextEdit* m_textEdit; QPlainTextEdit* m_plainEdit; QCheckBox* m_checkBox; QRadioButton* m_radioBtn; QComboBox* m_comboBox; QSlider* m_slider; QTableWidget* m_tableWidget; QTreeWidget* m_treeWidget; }; #endif // MAINWINDOW_Hmainwindow.cpp#include mainwindow.h #include QVBoxLayout #include QPushButton #include QLabel #include QLineEdit #include QTextEdit #include QPlainTextEdit #include QCheckBox #include QRadioButton #include QComboBox #include QSlider #include QTableWidget #include QTreeWidget MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { this-setWindowTitle(test); this-resize(400, 600); // 1. 创建垂直布局 QVBoxLayout* layout new QVBoxLayout(this); layout-setSpacing(6); layout-setContentsMargins(10,10,10,10); // 2. 逐个创建控件并加入布局 m_btn new QPushButton(QPushButton 按钮, this); layout-addWidget(m_btn); m_label new QLabel(QLabel 文本显示, this); layout-addWidget(m_label); m_lineEdit new QLineEdit(QLineEdit 单行输入, this); layout-addWidget(m_lineEdit); m_textEdit new QTextEdit(QTextEdit 富文本多行框, this); m_textEdit-setMaximumHeight(80); layout-addWidget(m_textEdit); m_plainEdit new QPlainTextEdit(QPlainTextEdit 纯文本多行框, this); m_plainEdit-setMaximumHeight(80); layout-addWidget(m_plainEdit); m_checkBox new QCheckBox(QCheckBox 复选框, this); layout-addWidget(m_checkBox); m_radioBtn new QRadioButton(QRadioButton 单选框, this); layout-addWidget(m_radioBtn); m_comboBox new QComboBox(this); m_comboBox-addItems({选项1,选项2,选项3}); layout-addWidget(m_comboBox); m_slider new QSlider(Qt::Horizontal, this); m_slider-setRange(0,100); layout-addWidget(m_slider); m_tableWidget new QTableWidget(2,2,this); m_tableWidget-setMaximumHeight(100); m_tableWidget-setHorizontalHeaderLabels({列1,列2}); layout-addWidget(m_tableWidget); m_treeWidget new QTreeWidget(this); m_treeWidget-setMaximumHeight(100); m_treeWidget-setHeaderLabel(树形控件); layout-addWidget(m_treeWidget); }最终效果
26.QT手撸布局+基础控件模板
纯代码写 UI 的优点1. 工程更干净无冗余文件没有.ui界面文件、没有 uic 编译器自动生成的ui_xxx.h中间代码整个项目只有.h和.cpp版本管理Git更清爽不会出现 UI 文件 XML 冲突多人协作时几乎不会出现 UI 文件合并冲突拖拽界面经常出现乱码、布局错乱的合并问题纯代码完全规避。2. 高度可控界面逻辑一体化界面创建、参数设置、信号绑定直接写在构造函数里界面和业务代码放在一起不用来回切换 UI 设计器和代码可以动态生成界面根据配置文件、网络数据、用户权限在运行时动态创建 / 销毁 / 增删控件。拖拽 UI 只能写死固定界面运行时想批量生成几十个按钮、表格列只能靠代码纯代码写法天然适配动态界面。3. 编译更快减少头文件依赖配合前置声明class QPushButton;头文件不需要引入一大堆控件头减少头文件嵌套大型项目编译速度提升明显不会因为包含过多 UI 头文件造成循环包含问题。4. 便于封装与复用可以把一组控件 布局封装成一个自定义控件类写成独立组件在多个窗口直接 new 调用纯代码组件移植性极强复制类文件就能复用不用连带复制 ui 文件。5. 方便版本回滚与代码审查所有界面改动都是 C 代码改动Git 可以清晰看到哪一行新增了按钮、修改了布局间距、调整了控件大小拖拽 UI 保存的是 XML 文本布局微小改动都会造成整段 XML 变动很难看清改了什么。6. 更容易实现精细化自定义如果要自己重写paintEvent绘制控件、自定义鼠标交互、做异形窗口、动画切换界面纯代码连贯开发更顺畅不用在设计师里摆放控件再去写自定义逻辑前后代码无缝衔接。7. 跨平台部署更省心少了 uic 编译环节编译链路更简单在 Linux、嵌入式 Qt 环境下交叉编译时少一个编译步骤不容易出编译环境问题。缺点这里暂不讨论main.cpp:#include QApplication #include mainwindow.h int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }mainwindow.h#ifndef MAINWINDOW_H #define MAINWINDOW_H #include QWidget class QPushButton; class QLabel; class QLineEdit; class QTextEdit; class QPlainTextEdit; class QCheckBox; class QRadioButton; class QComboBox; class QSlider; class QTableWidget; class QTreeWidget; class MainWindow : public QWidget { Q_OBJECT public: explicit MainWindow(QWidget *parent nullptr); private: QPushButton* m_btn; QLabel* m_label; QLineEdit* m_lineEdit; QTextEdit* m_textEdit; QPlainTextEdit* m_plainEdit; QCheckBox* m_checkBox; QRadioButton* m_radioBtn; QComboBox* m_comboBox; QSlider* m_slider; QTableWidget* m_tableWidget; QTreeWidget* m_treeWidget; }; #endif // MAINWINDOW_Hmainwindow.cpp#include mainwindow.h #include QVBoxLayout #include QPushButton #include QLabel #include QLineEdit #include QTextEdit #include QPlainTextEdit #include QCheckBox #include QRadioButton #include QComboBox #include QSlider #include QTableWidget #include QTreeWidget MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { this-setWindowTitle(test); this-resize(400, 600); // 1. 创建垂直布局 QVBoxLayout* layout new QVBoxLayout(this); layout-setSpacing(6); layout-setContentsMargins(10,10,10,10); // 2. 逐个创建控件并加入布局 m_btn new QPushButton(QPushButton 按钮, this); layout-addWidget(m_btn); m_label new QLabel(QLabel 文本显示, this); layout-addWidget(m_label); m_lineEdit new QLineEdit(QLineEdit 单行输入, this); layout-addWidget(m_lineEdit); m_textEdit new QTextEdit(QTextEdit 富文本多行框, this); m_textEdit-setMaximumHeight(80); layout-addWidget(m_textEdit); m_plainEdit new QPlainTextEdit(QPlainTextEdit 纯文本多行框, this); m_plainEdit-setMaximumHeight(80); layout-addWidget(m_plainEdit); m_checkBox new QCheckBox(QCheckBox 复选框, this); layout-addWidget(m_checkBox); m_radioBtn new QRadioButton(QRadioButton 单选框, this); layout-addWidget(m_radioBtn); m_comboBox new QComboBox(this); m_comboBox-addItems({选项1,选项2,选项3}); layout-addWidget(m_comboBox); m_slider new QSlider(Qt::Horizontal, this); m_slider-setRange(0,100); layout-addWidget(m_slider); m_tableWidget new QTableWidget(2,2,this); m_tableWidget-setMaximumHeight(100); m_tableWidget-setHorizontalHeaderLabels({列1,列2}); layout-addWidget(m_tableWidget); m_treeWidget new QTreeWidget(this); m_treeWidget-setMaximumHeight(100); m_treeWidget-setHeaderLabel(树形控件); layout-addWidget(m_treeWidget); }最终效果