3、Qt基础控件(下):QComboBox、QListWidget、QTableWidget、QTreeWidget、QTabWidget
好,咱们接着聊Qt的基础控件。上一节我们把按钮、输入框这些常用的讲完了,这一节要上点硬菜了——QComboBox、QListWidget、QTableWidget、QTreeWidget 和 QTabWidget。
这几个控件,说白了就是用来展示和选择数据的。你想想看,一个正经的桌面软件,哪个能少了下拉框、列表、表格、树形结构?我当年刚入行时,第一个项目就是个数据管理工具,天天跟这几个控件打交道。嗯,踩过的坑还真不少,今天一并给你抖出来。
核心知识点一览:
- QComboBox:下拉选择框,适合单选场景
- QListWidget:列表控件,支持单选/多选
- QTableWidget:表格控件,行列数据展示
- QTreeWidget:树形控件,层级结构展示
- QTabWidget:标签页控件,多页面切换
3.1 QComboBox:下拉选择框
QComboBox 这东西,说白了就是一个下拉菜单。用户点一下,弹出一堆选项,选一个完事。最常见的场景就是「选择性别」、「选择城市」这种。
我个人习惯用 addItem() 来添加选项,简单直接。但如果你要存一些额外数据(比如用户ID),那就得用 addItem(text, userData) 这种重载版本。
// 基本用法
QComboBox *combo = new QComboBox(this);
combo->addItem("北京");
combo->addItem("上海");
combo->addItem("广州");
// 带数据的用法
combo->addItem("张三", QVariant(1001));
combo->addItem("李四", QVariant(1002));
// 获取当前选中
QString city = combo->currentText();
int userId = combo->currentData().toInt();
小技巧: 如果你想让用户能输入自定义内容,记得设置 setEditable(true)。我在做搜索框时经常这么干,用户体验会好很多。
注意: 信号 currentIndexChanged(int) 在代码中设置索引时也会触发。如果你不想这样,可以先 blockSignals(true),设置完再恢复。
3.2 QListWidget:列表控件
QListWidget 比 QComboBox 更灵活。它可以展示多行数据,支持单选、多选,还能加图标。我当年做文件管理器时,左侧的文件列表就是用这个做的。
嗯,这里要注意:如果你只是简单展示文本,用 addItem() 就够了。但如果你需要自定义样式,那就得用 setItemWidget() 或者自定义 delegate。
QListWidget *list = new QListWidget(this);
list->addItem("文档");
list->addItem("图片");
list->addItem("视频");
// 设置选择模式
list->setSelectionMode(QAbstractItemView::MultiSelection);
// 获取选中的项
QList<QListWidgetItem*> items = list->selectedItems();
foreach(QListWidgetItem *item, items) {
qDebug() << item->text();
}
避坑指南: 我曾经在批量删除列表项时踩过坑——直接遍历删除会导致索引错乱。正确做法是从后往前删,或者用 takeItem() 配合临时列表。
3.3 QTableWidget:表格控件
表格控件,这个太常用了。数据显示、编辑、排序,样样都行。QTableWidget 是 QTableView 的简易版,适合数据量不大的场景。
我个人习惯先设置行列数,再填充数据。如果你需要动态添加行,用 insertRow() 就行。
QTableWidget *table = new QTableWidget(3, 4, this); // 3行4列
table->setHorizontalHeaderLabels({"姓名", "年龄", "城市", "职业"});
// 填充数据
table->setItem(0, 0, new QTableWidgetItem("张三"));
table->setItem(0, 1, new QTableWidgetItem("28"));
table->setItem(0, 2, new QTableWidgetItem("北京"));
table->setItem(0, 3, new QTableWidgetItem("工程师"));
// 设置整行选中
table->setSelectionBehavior(QAbstractItemView::SelectRows);
小技巧: 想让表格不可编辑?设置 table->setEditTriggers(QAbstractItemView::NoEditTriggers)。我在做数据展示时必加这一行,防止用户误操作。
3.4 QTreeWidget:树形控件
树形控件,用来展示层级结构。比如文件目录、组织架构、分类导航。QTreeWidget 用起来比 QTreeView 简单,适合中小规模的数据。
你想想看,一个树形结构,根节点下面有子节点,子节点下面还有子节点。用 addTopLevelItem() 添加根节点,再用根节点的 addChild() 添加子节点。
QTreeWidget *tree = new QTreeWidget(this);
tree->setHeaderLabels({"名称", "类型", "大小"});
// 创建根节点
QTreeWidgetItem *root = new QTreeWidgetItem(tree);
root->setText(0, "项目文件");
root->setText(1, "文件夹");
// 创建子节点
QTreeWidgetItem *child = new QTreeWidgetItem(root);
child->setText(0, "main.cpp");
child->setText(1, "源文件");
child->setText(2, "2 KB");
// 展开所有节点
tree->expandAll();
注意: 树形控件如果节点太多,展开时会卡顿。我建议用懒加载——只在用户展开节点时才加载子节点。监听 itemExpanded 信号即可。
3.5 QTabWidget:标签页控件
QTabWidget 用来做多页面切换。比如设置界面,一个标签页放「基本设置」,另一个放「高级设置」。这个控件本身不复杂,但用好了能让界面整洁很多。
我记得有个项目,客户要求把十几个配置项塞到一个窗口里。我直接用 QTabWidget 分了四个标签页,瞬间清爽了。
QTabWidget *tab = new QTabWidget(this);
QWidget *page1 = new QWidget();
QWidget *page2 = new QWidget();
// 往页面里加控件
QVBoxLayout *layout1 = new QVBoxLayout(page1);
layout1->addWidget(new QLabel("这是第一个标签页"));
QVBoxLayout *layout2 = new QVBoxLayout(page2);
layout2->addWidget(new QLabel("这是第二个标签页"));
tab->addTab(page1, "基本设置");
tab->addTab(page2, "高级设置");
// 设置当前标签页
tab->setCurrentIndex(0);
小技巧: 如果你想让标签页可以关闭,设置 setTabsClosable(true),然后连接 tabCloseRequested(int) 信号。我在做多文档编辑器时就是这么干的。
3.6 综合示例:一个简单的数据管理界面
好了,理论讲完了,咱们来个综合示例。把上面几个控件串起来,做一个简单的数据管理界面。
// 主窗口构造函数中
QVBoxLayout *mainLayout = new QVBoxLayout(this);
// 顶部:下拉框选择数据类别
QComboBox *combo = new QComboBox(this);
combo->addItem("员工信息");
combo->addItem("客户信息");
// 中间:表格展示数据
QTableWidget *table = new QTableWidget(this);
table->setColumnCount(4);
table->setHorizontalHeaderLabels({"ID", "姓名", "部门", "职位"});
// 底部:树形展示组织结构
QTreeWidget *tree = new QTreeWidget(this);
tree->setHeaderLabels({"部门", "负责人"});
// 用标签页整合
QTabWidget *tab = new QTabWidget(this);
tab->addTab(table, "数据列表");
tab->addTab(tree, "组织结构");
mainLayout->addWidget(combo);
mainLayout->addWidget(tab);
这个例子虽然简单,但已经涵盖了大部分日常开发场景。你想想看,一个后台管理系统,无非就是下拉框选类别、表格看数据、树形看结构,再用标签页把不同功能模块分开。
好了,这一节的内容就到这。这几个控件是 Qt 桌面开发的基石,一定要多练。下一节咱们会讲更高级的 Model/View 架构,到时候你会发现,原来这些控件还有更强大的玩法。
总结一下:
- QComboBox:单选下拉,适合选项少的场景
- QListWidget:列表展示,支持多选和图标
- QTableWidget:表格数据,行列清晰
- QTreeWidget:树形结构,层级分明
- QTabWidget:多页切换,界面整洁
可可精品资料库