多元素控件
多元素控件
Qt 中提供的多元素控件有:
- QListWidget
- QListView
- QTableWidget
- QTableView
- QTreeWidget
- QTreeView
xxWidget 和 xxView 之间的区别,以 QTableWidget 和 QTableView 为例:
- QTableView 是基于 MVC 设计的控件. QTableView ⾃⾝不持有数据. 使⽤ QTableView 的时候需要⽤⼾创建⼀个 Model 对象 (⽐如 QStandardModel ), 并且把 Model 和 QTableView 关联起来. 后续修改 Model 中的数据就会影响 QTableView 的显⽰; 修改 QTableView 的显⽰也会影响到 Model 中的数据(双向绑定).
- QTableWidget 则是 QTableView 的⼦类, 对 Model 进⾏了封装. 不需要用户手动创建 Model 对象, 直接就可以往 QTableWidget 中添加数据了.
1. List Widget
使用 QListWidget 能够显示⼀个纵向的列表. 形如:
核心属性:
核心方法:
核心信号:
在上述介绍中,涉及到⼀个关键的类,QListWidgetItem,这个类表⽰ QListWidget 中的⼀个元素,核心方法如下, 本质上就是⼀个 “⽂本+图标” 构成的。
代码示例:使用 ListWidget
1)在界⾯上创建⼀个 ListView,右键 => 变形为 => ListWidget ,再创建⼀个 lineEdit 和 两个按钮.
注意: ListWidget 是 ListView 的⼦类,功能⽐ ListView 更丰富,咱们使⽤ ListWidget 即可.
2)编写 widget.cpp, 在构造函数中添加初始元素
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); ui->listWidget->addItem("C++"); ui->listWidget->addItem("Java"); ui->listWidget->addItem("Python"); }
3)编写 listWidget 的 slot 函数
此处需要判定 current 和 previous ⾮空. 初始情况下是没有元素选中的,就导致这俩指针可能是 NULL;这⾥需要给 widget.h 前⾯加上 #include < QListWidgetItem >
void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) { if(current && previous){ qDebug() << "当前选中: " << current->text() << "之前选中: " << previous->text(); } }
4)编写按钮的 slot 函数
void Widget::on_pushButton_clicked() { // 获取到输入框的内容 const QString& text = ui->lineEdit->text(); if(text.isEmpty()){ return; } ui->listWidget->addItem(text); } void Widget::on_pushButton_2_clicked() { // 获取当前被选中的元素 int row = ui->listWidget->currentRow(); // 删除这一行 ui->listWidget->takeItem(row); }
2. Table Widget
使⽤ QTableWidget 表⽰⼀个表格控件。⼀个表格中包含若⼲⾏,每⼀⾏⼜包含若⼲列。表格中的每个单元格,是⼀个 QTableWidgetItem 对象。
QTableWidget 核心方法:
QTableWidgetItem 核心信号:
QTableWidgetItem 核心方法:
代码示例:使用 QTableWidget
1)在界⾯上创建 QTableWidget 和 三个按钮,⼀个输⼊框
注意:QTableWidget 是 QTableView 的⼦类,功能⽐ QTableView 更丰富. 咱们使⽤ QTableWidget 即可.
2)编写 widget.cpp 构造函数,构造表格中的初始数据
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // 创建 3 行 ui->tableWidget->insertRow(0); ui->tableWidget->insertRow(1); ui->tableWidget->insertRow(2); // 创建 3 列 ui->tableWidget->insertColumn(0); ui->tableWidget->insertColumn(1); ui->tableWidget->insertColumn(2); // 给 3 列设置列名 ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("学号")); ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("姓名")); ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("年龄")); // 设置初始数据 ui->tableWidget->setItem(0, 0, new QTableWidgetItem("1001")); ui->tableWidget->setItem(0, 1, new QTableWidgetItem("张三")); ui->tableWidget->setItem(0, 2, new QTableWidgetItem("20")); ui->tableWidget->setItem(1, 0, new QTableWidgetItem("1002")); ui->tableWidget->setItem(1, 1, new QTableWidgetItem("李四")); ui->tableWidget->setItem(1, 2, new QTableWidgetItem("21")); ui->tableWidget->setItem(2, 0, new QTableWidgetItem("1003")); ui->tableWidget->setItem(2, 1, new QTableWidgetItem("王五")); ui->tableWidget->setItem(2, 2, new QTableWidgetItem("22")); }
3)编写按钮的 slot 函数
void Widget::on_pushButton_addRow_clicked() { // 获取到行数 int row = ui->tableWidget->rowCount(); // 插入新行 ui->tableWidget->insertRow(row); } void Widget::on_pushButton_delRow_clicked() { // 获取到选中行 int row = ui->tableWidget->currentRow(); // 删除行 ui->tableWidget->removeRow(row); } void Widget::on_pushButton_addCol_clicked() { // 获取到列数 int col = ui->tableWidget->columnCount(); // 插入新列 ui->tableWidget->insertColumn(col); // 设置列名 const QString& name = ui->lineEdit->text(); ui->tableWidget->setHorizontalHeaderItem(col, new QTableWidgetItem(name)); } void Widget::on_pushButton_delCol_clicked() { // 获取到选中列 int col = ui->tableWidget->currentColumn(); // 删除 ui->tableWidget->removeColumn(col); }
默认情况下,单元格中的内容直接就是可编辑的。如果不想让⽤⼾编辑, 可以设置
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
3. Tree Widget
使⽤ QTreeWidget 表⽰⼀个树形控件。里面的每个元素, 都是⼀个 QTreeWidgetItem , 每个 QTreeWidgetItem 可以包含多个⽂本和图标, 每个⽂本/图标为⼀个 列.
可以给 QTreeWidget 设置顶层节点(顶层节点可以有多个), 然后再给顶层节点添加⼦节点, 从而构成树形结构.
QTreeWidget 核心方法:
QTreeWidget 核心信号:
QTreeWidgetItem 核心属性:
QTreeWidgetItem 核心方法:
代码示例:使用 QTreeWidget
1)在界⾯上创建⼀个 TreeView , 右键 => 变形为 => TreeWidget , 再创建⼀个 lineEdit 和 两个按钮.
注意: TreeWidget 是 TreeView 的⼦类, 功能⽐ TreeView 更丰富. 咱们使⽤ TreeWidget 即可.
2)编写代码, 构造初始数据
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); ui->treeWidget->setHeaderLabel("动物"); QTreeWidgetItem* item1 = new QTreeWidgetItem(); item1->setText(0, "猫"); ui->treeWidget->addTopLevelItem(item1); QTreeWidgetItem* item2 = new QTreeWidgetItem(); item2->setText(0, "狗"); ui->treeWidget->addTopLevelItem(item2); QTreeWidgetItem* item3 = new QTreeWidgetItem(); item3->setText(0, "鸟"); ui->treeWidget->addTopLevelItem(item3); }
3)编写代码, 实现按钮的 slot 函数
void Widget::on_pushButton_clicked() { // 获取输入框内容 const QString& text = ui->lineEdit->text(); if(text.isEmpty()){ return; } // 添加到顶层节点中 QTreeWidgetItem* item = new QTreeWidgetItem(); item->setText(0, text); ui->treeWidget->addTopLevelItem(item); } void Widget::on_pushButton_2_clicked() { // 获取输入框内容 const QString& text = ui->lineEdit->text(); if(text.isEmpty()){ return; } // 获取到当前选中元素 QTreeWidgetItem* currentItem = ui->treeWidget->currentItem(); if(currentItem == NULL){ return; } // 构造新的 item QTreeWidgetItem* newItem = new QTreeWidgetItem(); newItem->setText(0, text); // 添加 item 到选中节点 currentItem->addChild(newItem); // 展开父节点 currentItem->setExpanded(true); } void Widget::on_pushButton_3_clicked() { // 获取到当前选中节点 QTreeWidgetItem* currentItem = ui->treeWidget->currentItem(); if(currentItem == NULL){ return; } // 获取当前节点的父节点 QTreeWidgetItem* parent = currentItem->parent(); if(parent == NULL){ // 如果是顶层节点 int index = ui->treeWidget->indexOfTopLevelItem(currentItem); ui->treeWidget->takeTopLevelItem(index); } else{ // 非顶层节点 parent->removeChild(currentItem); } }