新疆维吾尔自治区网站建设_网站建设公司_H5网站_seo优化
2025/12/18 22:22:26 网站建设 项目流程

Qt 视图窗口核心分类

Qt 视图窗口分为 Item-Based(基于项)和 Model-Based(基于模型)两类,核心区别如下:

类型 核心特点 典型控件
Item-Based 直接操作控件的「项」(Item)实现数据更新,数据与视图耦合度高 QListWidget、QTableWidget、QTreeWidget
Model-Based 数据存储在「模型」中,视图仅负责展示,数据与视图解耦,支持实时更新、数据共享 QListView、QTableView、QTreeView

基础模型类说明(Model-Based 核心)

所有模型类均继承自 QAbstractItemModel,以下是常用模型的核心作用:

  • QAbstractListModel:抽象列表模型,定义列表数据的基础接口(需子类化实现具体逻辑)。
  • QAbstractTableModel:抽象表格模型,定义表格数据的基础接口(需子类化实现具体逻辑)。
  • QAbstractProxyModel:抽象代理模型,用于对已有模型做数据转换(如排序、过滤、合并)。
  • QConcatenateTablesProxyModel:代理模型,将多个表格模型按行拼接为一个模型。
  • QDirModel:已废弃(Qt5+ 推荐 QFileSystemModel),用于访问文件系统目录结构。
  • QFileSystemModel:文件系统模型,实时获取本地文件/目录信息(支持动态更新)。
  • QStandardItemModel:通用标准模型,无需子类化即可快速实现列表/表格/树形数据存储(简化 Model-Based 开发)。

Item-Based 核心控件

QListWidget(列表控件)

image

核心概念

以列表形式展示项(文本、图标、自定义控件),直接操作 QListWidgetItem 实现数据管理,适用于简单列表场景。

基础操作:添加内容

添加纯文本项

/*** 添加单个文本项到列表末尾* @brief addItem* @param label 要显示的文本内容* @return void 无返回值*/
ui->listWidget->addItem("Hello Widget");/*** 批量添加文本项到列表末尾* @brief addItems* @param labels 文本列表(QStringList)* @return void 无返回值*/
QStringList strList;
strList << "123" << "456" << "789" << "000";
ui->listWidget->addItems(strList);

image

添加带图标的项

/*** 构造带图标和文本的列表项* @brief QListWidgetItem 构造函数* @param icon 项的图标(QIcon),支持本地图片路径/资源文件* @param text 项的文本内容* @param parent 所属的QListWidget(可选)* @return QListWidgetItem* 构造的项对象(需手动管理内存)*/
QListWidgetItem *item = new QListWidgetItem(QIcon("./img/123.jpg"), "Hello Icon");
/*** 添加自定义项到列表末尾* @brief addItem* @param item 已构造的QListWidgetItem对象* @return void 无返回值*/
ui->listWidget->addItem(item);

image

添加自定义控件/窗口

image

// 1. 构造自定义窗口(如自定义的Friend窗口)
Friend *newFriend = new Friend();// 2. 构造空白列表项(仅作为载体)
QListWidgetItem *newItem = new QListWidgetItem();
ui->listWidget->addItem(newItem);/*** 设置列表项的尺寸(匹配自定义窗口大小)* @brief setSizeHint* @param size 目标尺寸(QSize),一般取自定义窗口的推荐尺寸* @return void 无返回值*/
newItem->setSizeHint(newFriend->sizeHint());/*** 给列表项绑定自定义控件* @brief setItemWidget* @param item 目标列表项* @param widget 要显示的自定义控件/窗口* @return void 无返回值*/
ui->listWidget->setItemWidget(newItem, newFriend);

信号与槽(核心交互)

信号 触发场景 参数说明
currentRowChanged(int) 当前选中行发生变化时 currentRow:新选中行的索引(从0开始)
currentTextChanged(QString) 当前选中项的文本发生变化时 currentText:新选中项的文本内容
itemClicked(QListWidgetItem*) 单击某一项时 item:被单击的项对象
itemDoubleClicked(QListWidgetItem*) 双击某一项时 item:被双击的项对象
itemSelectionChanged() 选中项发生变化时(无参数) -

示例1:获取选中行/文本

image

/*** 选中行变化时触发的槽函数* @brief on_listWidget_currentRowChanged* @param currentRow 新选中行的索引(-1表示无选中)* @return void 无返回值*/
void MainWindow::on_listWidget_currentRowChanged(int currentRow)
{qDebug() << "当前选中行:" << currentRow;
}

image

/*** 选中项文本变化时触发的槽函数* @brief on_listWidget_currentTextChanged* @param currentText 新选中项的文本* @return void 无返回值*/
void MainWindow::on_listWidget_currentTextChanged(const QString &currentText)
{qDebug() << "当前选中文本:" << currentText;ui->groupBox->setTitle(currentText); // 同步更新分组框标题
}

image

示例2:双击删除项

/*** 双击项时删除该项目* @brief on_listWidget_itemDoubleClicked* @param item 被双击的项对象* @return void 无返回值* @note removeItemWidget仅移除项内的控件,不删除项;takeItem删除项并返回对象(需手动释放内存)*/
void MainWindow::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{int row = ui->listWidget->row(item); // 获取项的行索引/*** 删除指定行的项* @brief takeItem* @param row 要删除的行索引* @return QListWidgetItem* 被删除的项对象(需手动delete释放,否则内存泄漏)*/QListWidgetItem *delItem = ui->listWidget->takeItem(row);delete delItem; // 释放内存
}

image

常用接口(QListWidget/QListWidgetItem)

QListWidget 核心接口

/*** 在指定行插入文本项* @brief insertItem* @param row 插入位置(索引)* @param text 文本内容* @return void 无返回值*/
ui->listWidget->insertItem(1, "插入到第2行的项");/*** 获取指定行的项对象* @brief item* @param row 目标行索引* @return QListWidgetItem* 目标行的项(NULL表示行不存在)*/
QListWidgetItem *targetItem = ui->listWidget->item(0);/*** 获取当前选中项* @brief currentItem* @return QListWidgetItem* 当前选中项(NULL表示无选中)*/
QListWidgetItem *curItem = ui->listWidget->currentItem();

QListWidgetItem 核心接口

/*** 设置项的文本颜色* @brief setTextColor* @param color 目标颜色(QColor)* @return void 无返回值*/
item->setTextColor(Qt::red);/*** 设置项的复选框状态* @brief setCheckState* @param state 复选状态(Qt::Unchecked/Checked/PartiallyChecked)* @return void 无返回值*/
item->setCheckState(Qt::Checked);/*** 设置项的提示文本(鼠标悬浮时显示)* @brief setToolTip* @param tip 提示文本* @return void 无返回值*/
item->setToolTip("这是一个带图标的项");

QTableWidget(表格控件)

核心概念

基于项的表格控件,直接操作 QTableWidgetItem 管理单元格数据,支持嵌入自定义控件,适用于简单表格场景。

基础操作:添加内容

初始化表格行列

/*** 设置表格行数* @brief setRowCount* @param rows 行数(正整数)* @return void 无返回值*/
ui->tableWidget->setRowCount(5);/*** 设置表格列数* @brief setColumnCount* @param columns 列数(正整数)* @return void 无返回值*/
ui->tableWidget->setColumnCount(3);/*** 设置水平表头标签* @brief setHorizontalHeaderLabels* @param labels 表头文本列表(QStringList)* @return void 无返回值*/
QStringList headerLabels;
headerLabels << "姓名" << "年龄" << "性别";
ui->tableWidget->setHorizontalHeaderLabels(headerLabels);

添加文本单元格

/*** 构造表格单元格项* @brief QTableWidgetItem 构造函数* @param text 单元格文本* @return QTableWidgetItem* 单元格项对象*/
QTableWidgetItem *newItem = new QTableWidgetItem("张三");/*** 设置指定单元格的项* @brief setItem* @param row 行索引(从0开始)* @param column 列索引(从0开始)* @param item 单元格项对象* @return void 无返回值*/
ui->tableWidget->setItem(0, 0, newItem);

添加自定义控件(如按钮)

/*** 构造自定义按钮* @brief QPushButton 构造函数* @param text 按钮文本* @param parent 父控件(可选)* @return QPushButton* 按钮对象*/
QPushButton *btn = new QPushButton("点击", this);
connect(btn, &QPushButton::clicked, []() {qDebug() << "表格内按钮被点击";
});/*** 设置指定单元格的自定义控件* @brief setCellWidget* @param row 行索引* @param column 列索引* @param widget 要嵌入的控件对象* @return void 无返回值*/
ui->tableWidget->setCellWidget(0, 2, btn);

image

表格布局优化

/*** 设置表头拉伸模式(最后一列填充剩余空间)* @brief setStretchLastSection* @param stretch 是否拉伸(true/false)* @return void 无返回值*/
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);/*** 设置所有列平均拉伸* @brief setSectionResizeMode* @param mode 拉伸模式(QHeaderView::Stretch 表示平均拉伸)* @return void 无返回值*/
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

核心信号

信号 触发场景 参数说明
cellClicked(int, int) 单击单元格时 row:行索引,column:列索引
cellDoubleClicked(int, int) 双击单元格时 row:行索引,column:列索引
currentCellChanged(int, int, int, int) 当前选中单元格变化时 当前行、当前列、之前行、之前列

QTreeWidget(树形控件)

核心概念

基于项的树形控件,通过 QTreeWidgetItem 构建层级结构,支持多列树形展示,适用于简单树形数据场景。

基础操作:构建树形结构

/*** 设置树形控件列数* @brief setColumnCount* @param columns 列数(默认1列)* @return void 无返回值*/
ui->treeWidget->setColumnCount(1);
ui->treeWidget->setHeaderLabel("树形结构示例");/*** 构造根节点* @brief QTreeWidgetItem 构造函数* @param parent 父节点(NULL表示根节点,也可传treeWidget)* @return QTreeWidgetItem* 节点对象*/
QTreeWidgetItem *rootItem = new QTreeWidgetItem(ui->treeWidget);
rootItem->setText(0, "根节点"); // 设置第0列文本/*** 构造子节点(父节点为rootItem)* @brief QTreeWidgetItem 构造函数* @param parent 父节点对象* @return QTreeWidgetItem* 子节点对象*/
QTreeWidgetItem *childItem1 = new QTreeWidgetItem(rootItem);
childItem1->setText(0, "一级子节点");/*** 构造孙子节点(父节点为childItem1)*/
QTreeWidgetItem *childItem2 = new QTreeWidgetItem(childItem1);
childItem2->setText(0, "二级子节点");/*公共槽函数*/
rootItem->expand(); // 展开根节点

image

常用接口

/*** 设置是否显示根节点的展开/折叠图标* @brief setRootIsDecorated* @param decorate 是否显示(true显示,false隐藏)* @return void 无返回值*/
ui->treeWidget->setRootIsDecorated(false);/*** 设置是否启用排序* @brief setSortingEnabled* @param enable 是否启用(true启用,false禁用)* @return void 无返回值*/
ui->treeWidget->setSortingEnabled(true);

Model-Based 核心控件:QTreeView

核心概念

基于模型的树形视图,必须配合模型使用(数据存储在模型,视图仅展示),支持实时更新、数据共享,适用于复杂/动态树形数据场景(如文件系统)。

核心接口

/*** 设置视图的数据源模型* @brief setModel* @param model 继承自QAbstractItemModel的模型对象* @return void 无返回值*/
void setModel(QAbstractItemModel *model);/*** 展开指定索引的节点* @brief expand* @param index 模型中的索引(QModelIndex)* @return void 无返回值*/
void expand(const QModelIndex &index);/*** 设置视图的根索引(仅展示模型中该索引下的子数据)* @brief setRootIndex* @param index 模型中的根索引* @return void 无返回值*/
void setRootIndex(const QModelIndex &index);

示例:展示文件系统

image

/*** 构造文件系统模型* @brief QFileSystemModel 构造函数* @param parent 父对象(可选)* @return QFileSystemModel* 模型对象*/
QFileSystemModel *fileModel = new QFileSystemModel(this);/*** 设置模型监控的根路径* @brief setRootPath* @param path 本地路径(如"D:/")* @return QString 标准化后的路径*/
fileModel->setRootPath("D:/");// 给QTreeView设置模型
ui->treeView->setModel(fileModel);/*** 获取指定路径在模型中的索引* @brief index* @param path 目标路径* @return QModelIndex 路径对应的模型索引*/
QModelIndex targetIndex = fileModel->index("D:/APP");// 设置视图仅展示"D:/APP"下的文件/目录
ui->treeView->setRootIndex(targetIndex);// 隐藏不需要的列(QFileSystemModel默认列:名称、大小、类型、修改时间)
ui->treeView->hideColumn(1);
ui->treeView->hideColumn(2);
ui->treeView->hideColumn(3);

image

Qt 多界面组件

MDI 窗口(Multiple Document Interface多文档界面)

核心概念

在一个主窗口内显示多个子窗口,子窗口可层叠/平铺,适用于同时编辑多个文档的场景(如多文本编辑器)。核心类:

  • QMdiArea:容纳子窗口的容器(需设置为QMainWindow的中央控件)。
  • QMdiSubWindow:MDI子窗口(可嵌入任意QWidget作为内容)。

示例代码

#include <QApplication>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QTextEdit>
#include <QMainWindow>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 1. 构造MDI容器/*** 构造MDI容器* @brief QMdiArea 构造函数* @param parent 父对象(可选)* @return QMdiArea* MDI容器对象*/QMdiArea *mdiArea = new QMdiArea;// 2. 构造第一个子窗口QMdiSubWindow *subWin1 = new QMdiSubWindow;QTextEdit *edit1 = new QTextEdit;/*** 设置子窗口的内容控件* @brief setWidget* @param widget 要嵌入的内容控件* @return void 无返回值*/subWin1->setWidget(edit1);subWin1->setWindowTitle("文档1"); // 设置子窗口标题// 3. 构造第二个子窗口QMdiSubWindow *subWin2 = new QMdiSubWindow;QTextEdit *edit2 = new QTextEdit;subWin2->setWidget(edit2);subWin2->setWindowTitle("文档2");// 4. 添加子窗口到MDI容器/*** 添加子窗口到MDI容器* @brief addSubWindow* @param subWindow MDI子窗口对象* @return QMdiSubWindow* 添加后的子窗口对象(与入参一致)*/mdiArea->addSubWindow(subWin1);mdiArea->addSubWindow(subWin2);// 5. 设置主窗口QMainWindow mainWin;mainWin.setCentralWidget(mdiArea); // MDI容器作为中央控件mainWin.setWindowTitle("MDI多文档示例");mainWin.resize(800, 600);// 6. 子窗口布局(平铺)/*** 平铺所有子窗口* @brief tileSubWindows* @return void 无返回值*/mdiArea->tileSubWindows();mainWin.show();return app.exec();
}

image

常用接口

/*** 层叠排列所有子窗口* @brief cascadeSubWindows* @return void 无返回值*/
mdiArea->cascadeSubWindows();/*** 设置活动子窗口* @brief setActiveSubWindow* @param subWindow 目标子窗口(NULL表示取消激活)* @return void 无返回值*/
mdiArea->setActiveSubWindow(subWin1);

Dock 窗口(停靠窗口)

核心概念

可浮动、可停靠在主窗口边缘的窗口,适用于工具栏、属性面板等场景。核心类:

  • QDockWidget:停靠窗口容器(需嵌入QMainWindow)。
  • QMainWindow:提供停靠区域(左/右/上/下)。

示例代码

#include <QApplication>
#include <QMainWindow>
#include <QDockWidget>
#include <QPushButton>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 1. 构造主窗口QMainWindow mainWin;mainWin.setWindowTitle("Dock停靠窗口示例");mainWin.resize(800, 600);// 2. 构造Dock窗口/*** 构造停靠窗口* @brief QDockWidget 构造函数* @param title 停靠窗口标题* @param parent 父对象(可选)* @return QDockWidget* 停靠窗口对象*/QDockWidget *dockWidget = new QDockWidget("工具栏", &mainWin);// 3. 构造Dock内容(按钮)QPushButton *btn = new QPushButton("停靠窗口按钮", dockWidget);dockWidget->setWidget(btn); // 设置Dock内容// 4. 设置Dock允许的停靠区域/*** 设置允许的停靠区域* @brief setAllowedAreas* @param areas 停靠区域(Qt::LeftDockWidgetArea/Right/Top/Bottom/AllDockWidgetAreas)* @return void 无返回值*/dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);// 5. 将Dock添加到主窗口左侧/*** 添加Dock窗口到主窗口* @brief addDockWidget* @param area 初始停靠区域* @param dockwidget 停靠窗口对象* @return void 无返回值*/mainWin.addDockWidget(Qt::LeftDockWidgetArea, dockWidget);mainWin.show();return app.exec();
}

image

QTabWidget(标签窗口)

核心概念

在一个窗口内通过标签切换多个页面,适用于分类展示不同内容(如多标签浏览器、配置面板)。

示例代码

#include <QApplication>
#include <QTabWidget>
#include <QTextEdit>
#include <QIcon>int main(int argc, char *argv[])
{QApplication app(argc, argv);// 1. 构造标签窗口QTabWidget *tabWidget = new QTabWidget;tabWidget->setWindowTitle("标签窗口示例");tabWidget->resize(600, 400);// 2. 添加标签页1(文本编辑器)/*** 添加标签页* @brief addTab* @param page 标签页内容控件* @param label 标签文本* @return int 标签页索引(从0开始)*/QTextEdit *edit1 = new QTextEdit;int tab1Index = tabWidget->addTab(edit1, "标签1");/*** 设置标签页图标* @brief setTabIcon* @param index 标签页索引* @param icon 图标(QIcon)* @return void 无返回值*/tabWidget->setTabIcon(tab1Index, QIcon(":/images/tab1.png"));// 3. 添加标签页2QTextEdit *edit2 = new QTextEdit;tabWidget->addTab(edit2, "标签2");// 4. 添加标签页3(禁用)QTextEdit *edit3 = new QTextEdit;int tab3Index = tabWidget->addTab(edit3, "标签3");/*** 设置标签页是否可用* @brief setTabEnabled* @param index 标签页索引* @param enabled 是否可用(true可用,false禁用)* @return void 无返回值*/tabWidget->setTabEnabled(tab3Index, false);// 5. 设置当前选中标签页/*** 设置当前选中标签页* @brief setCurrentIndex* @param index 标签页索引* @return void 无返回值*/tabWidget->setCurrentIndex(1); // 选中第二个标签页// 6. 开启标签页可关闭(显示×按钮)/*** 设置标签页是否可关闭* @brief setTabsClosable* @param closable 是否可关闭(true显示关闭按钮)* @return void 无返回值*/tabWidget->setTabsClosable(true);tabWidget->show();return app.exec();
}

image

常用接口

/*** 移除指定标签页* @brief removeTab* @param index 标签页索引* @return void 无返回值* @note 仅移除标签页,内容控件需手动释放内存*/
tabWidget->removeTab(0);/*** 获取标签页数量* @brief count* @return int 标签页数量(正整数)*/
int tabCount = tabWidget->count();/*** 设置标签页可拖动* @brief setMovable* @param movable 是否可拖动(true允许拖动调整顺序)* @return void 无返回值*/
tabWidget->setMovable(true);

关键注意事项

  • 内存管理:Item-Based 控件中,takeItem/takeRow 仅移除项,需手动 delete 释放对象;Model-Based 控件中,模型负责数据内存管理,视图仅展示。
  • 性能优化:大量数据场景优先使用 Model-Based 控件(如 QTableView 替代 QTableWidget),避免 Item-Based 控件的性能瓶颈。
  • 自定义控件嵌入:QListWidget/QTableWidget 嵌入自定义控件时,需通过 setSizeHint 匹配项/单元格尺寸,否则控件可能显示不全。
  • 信号与槽参数:QListWidget/QTableWidget 的信号参数(如 currentRowChanged)中,索引从 0 开始,-1 表示无选中项。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询