本帖最后由 正点原子运营 于 2022-7-29 15:40 编辑
1)实验平台:正点原子阿尔法Linux开发板
2) 章节摘自【正点原子】《I.MX6U 嵌入式Qt开发指南》
3)购买链接:https://detail.tmall.com/item.htm?id=609033604451
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/arm-linux/zdyz-i.mx6ull.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子阿尔法Linux交流群:1027879335
第七章 Qt控件
7.9 项目控件组(基于项)
在上一小节学习过视图组,下面学习控件组。仔细观察视图组里的某几个控件与控件组的控件名字相似。以QListWidget为例,QListWidget就是继承QListView。QListView是基于模型的,而QListWidget是基于项的。两种控件在不同的场合可以酌情选择使用!一般处理大数据使用基于模型的多。视图组与控件组的控件在Qt里展示数据时是会经常使用的!大家要掌握它们的使用方法。 以上各个控件的解释如下: (1) List Widget:清单控件 (2) TreeWidget:树形控件 (3) Table Widget:表控件 以下是各个控件的简介: QListWidget继承QListView。QListWidget类提供了一个基于项的列表小部件。QListWidget是一个便捷的类,它提供了一个类似于QListView(下一小节将讲到)提供的列表视图,但是提供了一个用于添加和删除项目的基于项目的经典接口。QListWidget使用内部模型来管理列表中的每个QListWidgetItem。QListView是基于model的,需要自己来建模(例如建立QStringListModel、QSqlTableModel等),保存数据,这样就大大降低了数据冗余,提高了程序的效率,但是需要我们对数据建模有一定了解,而QListWidget是一个升级版本的QListView,它已经自己为我们建立了一个数据存储模型(QListWidgetItem),操作方便,直接调用addItem即可添加项目(ICON,文字)。 QTreeWidget继承QTreeView。QTreeWidget类提供了一个使用预定义树模型的树视图。 QTreeWidget类是一个便捷的类,它提供了一个标准的树小部件,具有一个类似于qt3中的QListView类所使用的基于项目的经典接口。该类基于Qt的模型/视图体系结构,并使用默认模型来保存项,每个项都是QTreeWidgetItem。 QTableWidget继承QTableView。QTableWidget类提供了一个带有默认模型的基于项的表视图。表小部件为应用程序提供标准的表显示工具。QTableWidget中的项由QTableWidgetItem提供。
7.9.1 QListWidget7.9.1.1 控件简介QListWidget继承QListView。QListWidget类提供了一个基于项的列表小部件。QListWidget是一个便捷的类,它提供了一个类似于QListView(下一小节将讲到)提供的列表视图,但是提供了一个用于添加和删除项目的基于项目的经典接口。QListWidget使用内部模型来管理列表中的每个QListWidgetItem。
7.9.1.2 用法示例例45_qlistwidget,添加“歌曲”(难度:简单)。本例使用一个QListWidget以及一个按钮,当单击按钮时,就会调用系统打开文件窗口,过滤mp3后缀的文件(本例使用touch 指令创建2个mp3后缀的文件,并不是真正的歌曲,在终端输入指令为touch 0.mp3 1.mp3,本例在项目下已经创建了两个以mp3为后缀的文件),当打开系统文件选择框时,就会选择这两个mp3文件作为QListWidget的项添加到QListWidget的窗口中。(PS:我们写音乐播放器就要用到这种操作—打开歌曲。实际本例就是一个打开歌曲的代码部分。) 在新建例程中不要勾选“Generate form”,默认继承QMainWindow类即可。项目新建完成,如下图。 在头文件“mainwindow.h”具体代码如下。 - mainwindow.h编程后的代码
- 1 #ifndef MAINWINDOW_H
- 2 #define MAINWINDOW_H
- 3
- 4 #include <QMainWindow>
- 5 #include <QListWidget>
- 6 #include <QPushButton>
- 7
- 8 class MainWindow : public QMainWindow
- 9 {
- 10 Q_OBJECT
- 11
- 12 public:
- 13 MainWindow(QWidget *parent = nullptr);
- 14 ~MainWindow();
- 15
- 16 private:
- 17 /* 声明对象 */
- 18 QListWidget *listWidget;
- 19 QPushButton *pushButton;
- 20
- 21 private slots:
- 22 void pushButtonClicked();
- 23
- 24 };
- 25 #endif // MAINWINDOW_H
复制代码在源文件“mainwindow.cpp”具体代码如下。 - mainwindow.cpp编程后的代码
- 1 #include "mainwindow.h"
- 2 #include "QFileDialog"
- 3
- 4 MainWindow::MainWindow(QWidget *parent)
- 5 : QMainWindow(parent)
- 6 {
- 7 /* 设置主窗口的显示位置与大小 */
- 8 this->setGeometry(0, 0, 800, 480);
- 9
- 10 listWidget = new QListWidget(this);
- 11
- 12 /* 设置listWidget的大小 */
- 13 listWidget->setGeometry(0, 0, 480, 480);
- 14
- 15 listWidget->addItem("请单击右边的添加项添加内容");
- 16
- 17 pushButton = new QPushButton(this);
- 18
- 19 /* 设置pushButton的位置与大小 */
- 20 pushButton->setGeometry(540, 200, 200, 100);
- 21 pushButton->setText("添加项");
- 22
- 23 /* 信号与槽连接 */
- 24 connect(pushButton, SIGNAL(clicked()),
- 25 this, SLOT(pushButtonClicked()));
- 26 }
- 27
- 28 void MainWindow::pushButtonClicked()
- 29 {
- 30 /* 调用系统打开文件窗口,设置窗口标题为“打开文件”,过滤文件名 */
- 31 QString fileName = QFileDialog::getOpenFileName(
- 32 this,tr("添加项"),"",
- 33 tr("Files(*.mp3)")
- 34 );
- 35
- 36 /* 判断是否选中打开mp3文件 */
- 37 if (fileName != NULL)
- 38 /* 添加项到列表中 */
- 39 listWidget->addItem(fileName);
- 40 }
- 41
- 42 MainWindow::~MainWindow()
- 43 {
- 44 }
复制代码在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。 - main.cpp编程后的代码
- 1 #include "mainwindow.h"
- 2
- 3 #include <QApplication>
- 4
- 5 int main(int argc, char *argv[])
- 6 {
- 7 QApplication a(argc, argv);
- 8 MainWindow w;
- 9 w.show();
- 10 return a.exec();
- 11 }
复制代码 7.9.1.3 运行效果程序编译运行的结果如下。当点击添加项按钮时出现系统选择文件的对话框,系统打开文件时会过滤mp3后缀的文件,点击后缀为mp3的文件,双击或者选择后再点击右上角的“Open”的打开来把这个文件添加到左边的QListWidget列表中。读者可以模仿这个示例,还可以添加删除项的按钮,或者删除全部按钮等,酷狗音乐播放器的的歌单与此类似。后续继续学习如何播放音乐,与此结合,就可以做出一款音乐播放器了。 7.9.2 QTreeWidget
7.9.2.1 控件简介QTreeWidget继承QTreeView。QTreeWidget类提供了一个使用预定义树模型的树视图。 QTreeWidget类是一个便捷的类,它提供了一个标准的树小部件,具有一个类似于qt3中的QListView类所使用的基于项目的经典接口。该类基于Qt的模型/视图体系结构,并使用默认模型来保存项,每个项都是QTreeWidgetItem。
7.9.2.2 用法示例例46_qtreewidget,群发信息(难度:一般),本例使用一个TreeWidget,模拟成一个飞信联系人分组,通过选中组内联系人来“群发”信息。实际并不是真正做一个群发信息的飞信,只是模拟飞信群发信息时选择联系人的场景,通过例子来熟悉QTreeWidget的使用。本例相对前面的例子稍长,出现了树节点与子节点的概念。本例的思路:当选中顶层的树形节点时,子节点全部被选中;当取消选择顶层树形节点时,子节点原来选中的状态将全部取消;当不完全选中子节点时,树节点显示为半选状态。 在新建例程中不要勾选“Generate form”,默认继承QMainWindow类即可。项目新建完成,如下图。 在头文件“mainwindow.h”具体代码如下。 - mainwindow.h编程后的代码
- 1 #ifndef MAINWINDOW_H
- 2 #define MAINWINDOW_H
- 3
- 4 #include <QMainWindow>
- 5 #include <QTreeWidget>
- 6 #include <QTreeWidgetItem>
- 7
- 8 class MainWindow : public QMainWindow
- 9 {
- 10 Q_OBJECT
- 11
- 12 public:
- 13 MainWindow(QWidget *parent = nullptr);
- 14 ~MainWindow();
- 15
- 16 private:
- 17 /* QTreeWidget对象 */
- 18 QTreeWidget *treeWidget;
- 19 /* 顶层树节点 */
- 20 QTreeWidgetItem *parentItem;
- 21 /* 声明三个子节点 */
- 22 QTreeWidgetItem *subItem[3];
- 23
- 24 /* 子节点处理函数 */
- 25 void updateParentItem(QTreeWidgetItem*);
- 26
- 27 private slots:
- 28 /* 槽函数 */
- 29 void treeItemChanged(QTreeWidgetItem*, int);
- 30
- 31 };
- 32 #endif // MAINWINDOW_H
复制代码在源文件“mainwindow.cpp”具体代码如下。 - mainwindow.cpp编程后的代码
- 1 #include "mainwindow.h"
- 2
- 3 MainWindow::MainWindow(QWidget *parent)
- 4 : QMainWindow(parent)
- 5 {
- 6 /* 设置主窗体大小 */
- 7 this->setGeometry(0, 0, 800, 480);
- 8
- 9 /* 实例化 */
- 10 treeWidget = new QTreeWidget(this);
- 11
- 12 /* 居中 */
- 13 setCentralWidget(treeWidget);
- 14
- 15 /* 清空列表 */
- 16 treeWidget->clear();
- 17
- 18 /* 实例化顶层树节点 */
- 19 parentItem = new QTreeWidgetItem(treeWidget);
- 20 parentItem->setText(0, "同事");
- 21
- 22 parentItem->setFlags(
- 23 Qt::ItemIsUserCheckable
- 24 | Qt::ItemIsEnabled
- 25 | Qt::ItemIsSelectable
- 26 );
- 27 /* 树节点设置为未选中 */
- 28 parentItem->setCheckState(0, Qt::Unchecked);
- 29
- 30 /* 字符串链表 */
- 31 QList <QString> strList;
- 32 strList<<"关羽"<<"刘备"<<"张飞";
- 33
- 34 for (int i = 0; i < 3; i++){
- 35 /* 实例化子节点 */
- 36 subItem[i] = new QTreeWidgetItem(parentItem);
- 37 /* 设置子节点的文本,参数0代表第0列 */
- 38 subItem[i]->setText(0, strList[i]);
- 39 /* 设置子节点的属性为用户可选、项开启、项可选 */
- 40 subItem[i]->setFlags(
- 41 Qt::ItemIsUserCheckable
- 42 | Qt::ItemIsEnabled
- 43 | Qt::ItemIsSelectable
- 44 );
- 45 /* 设置子节点的状态为未选中 */
- 46 subItem[i]->setCheckState(0,Qt::Unchecked);
- 47 }
- 48 /* 信号槽连接 */
- 49 connect(treeWidget,SIGNAL(itemChanged(QTreeWidgetItem* , int)),
- 50 this, SLOT(treeItemChanged(QTreeWidgetItem* , int)));
- 51
- 52 }
- 53
- 54 /* 更新树节点函数 */
- 55 void MainWindow::updateParentItem(QTreeWidgetItem *item)
- 56 {
- 57 /* 获取子节点的父节点(树节点) */
- 58 QTreeWidgetItem* parent = item->parent();
- 59 if(parent == NULL){
- 60 return;
- 61 }
- 62 /* 初始化选中的数目为0,下面根据selectCount来判断树节点的状态 */
- 63 int selectCount = 0;
- 64 /* 获取树节点的子节点总数 */
- 65 int childCount = parent->childCount();
- 66 /* 循环判断子节点的状态 */
- 67 for(int i = 0; i < childCount; i ++){
- 68 QTreeWidgetItem* childItem =parent->child(i);
- 69 /* 判断当前子节点的状是否为选中状态,如果是,则加一 */
- 70 if(childItem->checkState(0) == Qt::Checked) {
- 71 selectCount ++;
- 72 }
- 73 }
- 74 /* 根据selectCount来判断树节点的状态 */
- 75 /* 当选中的子节点小于或等于0时,则为设置树节点为未选中状态 */
- 76 if (selectCount <= 0) {
- 77 /* 设置树节点为未选中状态 */
- 78 parent->setCheckState(0, Qt::Unchecked);
- 79 /* 部分选中时,树节点为半选状态 */
- 80 } else if (selectCount > 0 && selectCount < childCount) {
- 81 /* 设置为半选状态 */
- 82 parent->setCheckState(0, Qt::PartiallyChecked);
- 83 /* 子节点全选时 */
- 84 } else if (selectCount == childCount){
- 85 /* 设置为树节点为选中状态 */
- 86 parent->setCheckState(0, Qt::Checked);
- 87 }
- 88 }
- 89
- 90 void MainWindow::treeItemChanged(QTreeWidgetItem *item, int)
- 91 {
- 92 /* 获取子节点总数 */
- 93 int count = item->childCount();
- 94
- 95 /* 若顶层树节点选中 */
- 96 if(Qt::Checked == item->checkState(0) ) {
- 97 /* 若选中的项是树节点,count会大于0,否则选中的项是子节点 */
- 98 if (count > 0) {
- 99 for (int i = 0; i < count; i++) {
- 100 /* 子节点全选 */
- 101 item->child(i)->setCheckState(0, Qt::Checked);
- 102 }
- 103 } else {
- 104 /* 子节点处理 */
- 105 updateParentItem(item);
- 106 }
- 107 /* 若顶层树节点取消选中时 */
- 108 } else if (Qt::Unchecked == item->checkState(0)) {
- 109 if (count > 0){
- 110 /* 若选中的项是树节点,count会大于0,否则选中的项是子节点 */
- 111 for (int i = 0; i < count; i++) {
- 112 /* 子节点全不选 */
- 113 item->child(i)->setCheckState(0, Qt::Unchecked);
- 114 }
- 115 } else {
- 116 /* 子节点处理 */
- 117 updateParentItem(item);
- 118 }
- 119 }
- 120 }
- 121
- 122 MainWindow::~MainWindow()
- 123 {
- 124 }
复制代码在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。 - main.cpp编程后的代码
- 1 #include "mainwindow.h"
- 2
- 3 #include <QApplication>
- 4
- 5 int main(int argc, char *argv[])
- 6 {
- 7 QApplication a(argc, argv);
- 8 MainWindow w;
- 9 w.show();
- 10 return a.exec();
- 11 }
复制代码 7.9.2.3 运行效果程序编译运行的结果如下。下图为全选时的状态,好比要群发信息时全选联系人的场景。当选中树节点同事时,子节点(关羽、刘备、张飞)将全选;当树节点同事未选中时,子节点(关羽、刘备、张飞)的状态为未选中;当子节点(关羽、刘备、张飞)选中且不全选时,树节点同事的状态将为半选状态。
7.9.3 QTableWidget
7.9.3.1 控件简介QTableWidget继承QTableView。QTableWidget类提供了一个带有默认模型的基于项的表视图。表小部件为应用程序提供标准的表显示工具。QTableWidget中的项由QTableWidgetItem提供。
7.9.3.2 用法示例例47_qtablewidget,TabelWidget表格(难度:简单),本例使用一个TableWidget,绘制一个表格,同时修改项的标题,在表格里可以直接通过双击进行编辑项里的内容,也可以删除项里的内容等。 在新建例程中不要勾选“Generate form”,默认继承QMainWindow类即可。项目新建完成,如下图。 在头文件“mainwindow.h”具体代码如下。 - mainwindow.h编程后的代码
- 1 #ifndef MAINWINDOW_H
- 2 #define MAINWINDOW_H
- 3
- 4 #include <QMainWindow>
- 5 #include <QTableWidget>
- 6
- 7 class MainWindow : public QMainWindow
- 8 {
- 9 Q_OBJECT
- 10
- 11 public:
- 12 MainWindow(QWidget *parent = nullptr);
- 13 ~MainWindow();
- 14
- 15 private:
- 16 /* QTabelWidget表格 */
- 17 QTableWidget *tableWidget;
- 18
- 19 /* QTabelWidgetItem表格数据(项) */
- 20 QTableWidgetItem *tableWidgetItem[4];
- 21
- 22 };
- 23 #endif // MAINWINDOW_H
复制代码在源文件“mainwindow.cpp”具体代码如下。 - mainwindow.cpp编程后的代码
- 1 #include "mainwindow.h"
- 2
- 3 MainWindow::MainWindow(QWidget *parent)
- 4 : QMainWindow(parent)
- 5 {
- 6 /* 设置主窗体的大小与位置 */
- 7 this->setGeometry(0, 0, 800, 480);
- 8
- 9 /* 实例化 */
- 10 tableWidget = new QTableWidget(this);
- 11 /* 设置tableWidget表居中 */
- 12 setCentralWidget(tableWidget);
- 13 /* 设置列数 */
- 14 tableWidget->setColumnCount(2);
- 15 /* 设置行数 */
- 16 tableWidget->setRowCount(2);
- 17 /* 使用标签设置水平标题标签 */
- 18 tableWidget->setHorizontalHeaderLabels(
- 19 QStringList()<<"姓名"<<"性别"
- 20 );
- 21
- 22 /* 字符串类型链表 */
- 23 QList <QString> strList;
- 24 strList<<"小明"<<"小红"<<"男"<<"女";
- 25
- 26 for (int i = 0; i < 4; i++) {
- 27 /* 实例化 */
- 28 tableWidgetItem[i] = new QTableWidgetItem(strList[i]);
- 29 /* 设置文本居中对齐 */
- 30 tableWidgetItem[i]->setTextAlignment(Qt::AlignCenter);
- 31 }
- 32 /* 插入数据,表的index就是一个二维数组数据 */
- 33 tableWidget->setItem(0, 0, tableWidgetItem[0]);
- 34 tableWidget->setItem(1, 0, tableWidgetItem[1]);
- 35 tableWidget->setItem(0, 1, tableWidgetItem[2]);
- 36 tableWidget->setItem(1, 1, tableWidgetItem[3]);
- 37
- 38 }
- 39
- 40 MainWindow::~MainWindow()
- 41 {
- 42 }
复制代码在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。 - main.cpp编程后的代码
- 1 #include "mainwindow.h"
- 2
- 3 #include <QApplication>
- 4
- 5 int main(int argc, char *argv[])
- 6 {
- 7 QApplication a(argc, argv);
- 8 MainWindow w;
- 9 w.show();
- 10 return a.exec();
- 11 }
复制代码
7.9.3.3 运行效果程序编译运行的结果如下。双击表格中的项,可修改表格的内容,同时也可以删除内容等。
|