OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2627|回复: 0

《I.MX6U 嵌入式Qt开发指南》第七章 Qt控件 7.9 项目控件组(基于项)

[复制链接]

1061

主题

1072

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4407
金钱
4407
注册时间
2019-5-8
在线时间
1196 小时
发表于 2022-7-29 15:41:09 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 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 项目控件组(基于项)
image002.jpg

       在上一小节学习过视图组,下面学习控件组。仔细观察视图组里的某几个控件与控件组的控件名字相似。以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类即可。项目新建完成,如下图。
image004.jpg
   在头文件“mainwindow.h”具体代码如下。
  1. mainwindow.h编程后的代码

  2. 1   #ifndef MAINWINDOW_H

  3. 2   #define MAINWINDOW_H

  4. 3

  5. 4   #include <QMainWindow>

  6. 5   #include <QListWidget>

  7. 6   #include <QPushButton>

  8. 7

  9. 8   class MainWindow : public QMainWindow

  10. 9   {

  11. 10      Q_OBJECT

  12. 11

  13. 12  public:

  14. 13      MainWindow(QWidget *parent = nullptr);

  15. 14      ~MainWindow();

  16. 15

  17. 16  private:

  18. 17      /* 声明对象 */

  19. 18      QListWidget *listWidget;

  20. 19      QPushButton *pushButton;

  21. 20

  22. 21  private slots:

  23. 22      void pushButtonClicked();

  24. 23

  25. 24  };

  26. 25  #endif // MAINWINDOW_H
复制代码
在源文件“mainwindow.cpp”具体代码如下。
  1. mainwindow.cpp编程后的代码

  2. 1   #include "mainwindow.h"

  3. 2   #include "QFileDialog"

  4. 3

  5. 4   MainWindow::MainWindow(QWidget *parent)

  6. 5       : QMainWindow(parent)

  7. 6   {

  8. 7       /* 设置主窗口的显示位置与大小 */

  9. 8       this->setGeometry(0, 0, 800, 480);

  10. 9

  11. 10      listWidget = new QListWidget(this);

  12. 11

  13. 12      /* 设置listWidget的大小 */

  14. 13      listWidget->setGeometry(0, 0, 480, 480);

  15. 14

  16. 15      listWidget->addItem("请单击右边的添加项添加内容");

  17. 16

  18. 17      pushButton = new QPushButton(this);

  19. 18

  20. 19      /* 设置pushButton的位置与大小 */

  21. 20      pushButton->setGeometry(540, 200, 200, 100);

  22. 21      pushButton->setText("添加项");

  23. 22

  24. 23      /* 信号与槽连接 */

  25. 24      connect(pushButton, SIGNAL(clicked()),

  26. 25              this, SLOT(pushButtonClicked()));

  27. 26  }

  28. 27

  29. 28  void MainWindow::pushButtonClicked()

  30. 29  {

  31. 30      /* 调用系统打开文件窗口,设置窗口标题为“打开文件”,过滤文件名 */

  32. 31      QString fileName = QFileDialog::getOpenFileName(

  33. 32                  this,tr("添加项"),"",

  34. 33                  tr("Files(*.mp3)")

  35. 34                  );

  36. 35

  37. 36      /* 判断是否选中打开mp3文件 */

  38. 37      if (fileName != NULL)

  39. 38          /* 添加项到列表中 */

  40. 39          listWidget->addItem(fileName);

  41. 40  }

  42. 41

  43. 42  MainWindow::~MainWindow()

  44. 43  {

  45. 44  }
复制代码
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。
  1. main.cpp编程后的代码

  2. 1   #include "mainwindow.h"

  3. 2

  4. 3   #include <QApplication>

  5. 4

  6. 5   int main(int argc, char *argv[])

  7. 6   {

  8. 7       QApplication a(argc, argv);

  9. 8       MainWindow w;

  10. 9       w.show();

  11. 10      return a.exec();

  12. 11  }
复制代码
7.9.1.3 运行效果
程序编译运行的结果如下。当点击添加项按钮时出现系统选择文件的对话框,系统打开文件时会过滤mp3后缀的文件,点击后缀为mp3的文件,双击或者选择后再点击右上角的“Open”的打开来把这个文件添加到左边的QListWidget列表中。读者可以模仿这个示例,还可以添加删除项的按钮,或者删除全部按钮等,酷狗音乐播放器的的歌单与此类似。后续继续学习如何播放音乐,与此结合,就可以做出一款音乐播放器了。
image006.jpg
image008.jpg
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类即可。项目新建完成,如下图。
image010.jpg
   在头文件“mainwindow.h”具体代码如下。
  1. mainwindow.h编程后的代码

  2. 1   #ifndef MAINWINDOW_H

  3. 2   #define MAINWINDOW_H

  4. 3

  5. 4   #include <QMainWindow>

  6. 5   #include <QTreeWidget>

  7. 6   #include <QTreeWidgetItem>

  8. 7

  9. 8   class MainWindow : public QMainWindow

  10. 9   {

  11. 10      Q_OBJECT

  12. 11

  13. 12  public:

  14. 13      MainWindow(QWidget *parent = nullptr);

  15. 14      ~MainWindow();

  16. 15

  17. 16  private:

  18. 17      /* QTreeWidget对象 */

  19. 18      QTreeWidget *treeWidget;

  20. 19      /* 顶层树节点 */

  21. 20      QTreeWidgetItem *parentItem;

  22. 21      /* 声明三个子节点 */

  23. 22      QTreeWidgetItem *subItem[3];

  24. 23

  25. 24      /* 子节点处理函数 */

  26. 25      void updateParentItem(QTreeWidgetItem*);

  27. 26

  28. 27  private slots:

  29. 28      /* 槽函数 */

  30. 29      void treeItemChanged(QTreeWidgetItem*, int);

  31. 30

  32. 31  };

  33. 32  #endif // MAINWINDOW_H
复制代码
在源文件“mainwindow.cpp”具体代码如下。
  1. mainwindow.cpp编程后的代码

  2. 1   #include "mainwindow.h"

  3. 2

  4. 3   MainWindow::MainWindow(QWidget *parent)

  5. 4       : QMainWindow(parent)

  6. 5   {

  7. 6       /* 设置主窗体大小 */

  8. 7       this->setGeometry(0, 0, 800, 480);

  9. 8      

  10. 9       /* 实例化 */

  11. 10      treeWidget = new QTreeWidget(this);

  12. 11     

  13. 12      /* 居中 */

  14. 13      setCentralWidget(treeWidget);

  15. 14     

  16. 15      /* 清空列表 */

  17. 16      treeWidget->clear();

  18. 17     

  19. 18      /* 实例化顶层树节点 */

  20. 19      parentItem = new QTreeWidgetItem(treeWidget);

  21. 20      parentItem->setText(0, "同事");

  22. 21     

  23. 22      parentItem->setFlags(

  24. 23                  Qt::ItemIsUserCheckable

  25. 24                  | Qt::ItemIsEnabled

  26. 25                  | Qt::ItemIsSelectable

  27. 26                  );

  28. 27      /* 树节点设置为未选中 */

  29. 28      parentItem->setCheckState(0, Qt::Unchecked);

  30. 29     

  31. 30      /* 字符串链表 */

  32. 31      QList <QString> strList;

  33. 32      strList<<"关羽"<<"刘备"<<"张飞";

  34. 33     

  35. 34      for (int i = 0; i < 3; i++){

  36. 35          /* 实例化子节点 */

  37. 36          subItem[i] = new QTreeWidgetItem(parentItem);

  38. 37          /* 设置子节点的文本,参数0代表第0列 */

  39. 38          subItem[i]->setText(0, strList[i]);

  40. 39          /* 设置子节点的属性为用户可选、项开启、项可选 */

  41. 40          subItem[i]->setFlags(

  42. 41                      Qt::ItemIsUserCheckable

  43. 42                      | Qt::ItemIsEnabled

  44. 43                      | Qt::ItemIsSelectable

  45. 44                      );

  46. 45          /* 设置子节点的状态为未选中 */

  47. 46          subItem[i]->setCheckState(0,Qt::Unchecked);

  48. 47      }

  49. 48      /* 信号槽连接 */

  50. 49      connect(treeWidget,SIGNAL(itemChanged(QTreeWidgetItem* , int)),

  51. 50              this, SLOT(treeItemChanged(QTreeWidgetItem* , int)));

  52. 51     

  53. 52  }

  54. 53

  55. 54  /* 更新树节点函数 */

  56. 55  void MainWindow::updateParentItem(QTreeWidgetItem *item)

  57. 56  {

  58. 57      /* 获取子节点的父节点(树节点) */

  59. 58      QTreeWidgetItem* parent = item->parent();

  60. 59      if(parent == NULL){

  61. 60          return;

  62. 61      }

  63. 62      /* 初始化选中的数目为0,下面根据selectCount来判断树节点的状态 */

  64. 63      int selectCount = 0;

  65. 64      /* 获取树节点的子节点总数 */

  66. 65      int childCount = parent->childCount();

  67. 66      /* 循环判断子节点的状态 */

  68. 67      for(int i = 0; i < childCount; i ++){

  69. 68          QTreeWidgetItem* childItem =parent->child(i);

  70. 69          /* 判断当前子节点的状是否为选中状态,如果是,则加一 */

  71. 70          if(childItem->checkState(0) == Qt::Checked) {

  72. 71              selectCount ++;

  73. 72          }

  74. 73      }

  75. 74      /* 根据selectCount来判断树节点的状态 */

  76. 75      /* 当选中的子节点小于或等于0时,则为设置树节点为未选中状态 */

  77. 76      if (selectCount <= 0) {

  78. 77          /* 设置树节点为未选中状态 */

  79. 78          parent->setCheckState(0, Qt::Unchecked);

  80. 79          /* 部分选中时,树节点为半选状态 */

  81. 80      } else if (selectCount > 0 && selectCount < childCount) {

  82. 81          /* 设置为半选状态 */

  83. 82          parent->setCheckState(0, Qt::PartiallyChecked);

  84. 83          /* 子节点全选时 */

  85. 84      } else if (selectCount == childCount){

  86. 85          /* 设置为树节点为选中状态 */

  87. 86          parent->setCheckState(0, Qt::Checked);

  88. 87      }

  89. 88  }

  90. 89

  91. 90  void MainWindow::treeItemChanged(QTreeWidgetItem *item, int)

  92. 91  {

  93. 92      /* 获取子节点总数 */

  94. 93      int count = item->childCount();

  95. 94     

  96. 95      /* 若顶层树节点选中 */

  97. 96      if(Qt::Checked == item->checkState(0) ) {

  98. 97          /* 若选中的项是树节点,count会大于0,否则选中的项是子节点 */

  99. 98          if (count > 0) {

  100. 99              for (int i = 0; i < count; i++) {

  101. 100                 /* 子节点全选 */

  102. 101                 item->child(i)->setCheckState(0, Qt::Checked);

  103. 102             }

  104. 103         } else {

  105. 104             /* 子节点处理 */

  106. 105             updateParentItem(item);

  107. 106         }

  108. 107         /* 若顶层树节点取消选中时 */

  109. 108     } else if (Qt::Unchecked == item->checkState(0)) {

  110. 109         if (count > 0){

  111. 110             /* 若选中的项是树节点,count会大于0,否则选中的项是子节点 */

  112. 111             for (int i = 0; i < count; i++) {

  113. 112                 /* 子节点全不选 */

  114. 113                 item->child(i)->setCheckState(0, Qt::Unchecked);

  115. 114             }

  116. 115         } else {

  117. 116             /* 子节点处理 */

  118. 117             updateParentItem(item);

  119. 118         }

  120. 119     }

  121. 120 }

  122. 121

  123. 122 MainWindow::~MainWindow()

  124. 123 {

  125. 124 }
复制代码
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。
  1. main.cpp编程后的代码

  2. 1   #include "mainwindow.h"

  3. 2

  4. 3   #include <QApplication>

  5. 4

  6. 5   int main(int argc, char *argv[])

  7. 6   {

  8. 7       QApplication a(argc, argv);

  9. 8       MainWindow w;

  10. 9       w.show();

  11. 10      return a.exec();

  12. 11  }
复制代码
7.9.2.3 运行效果
程序编译运行的结果如下。下图为全选时的状态,好比要群发信息时全选联系人的场景。当选中树节点同事时,子节点(关羽、刘备、张飞)将全选;当树节点同事未选中时,子节点(关羽、刘备、张飞)的状态为未选中;当子节点(关羽、刘备、张飞)选中且不全选时,树节点同事的状态将为半选状态。
image012.jpg

7.9.3 QTableWidget
7.9.3.1 控件简介
QTableWidget继承QTableView。QTableWidget类提供了一个带有默认模型的基于项的表视图。表小部件为应用程序提供标准的表显示工具。QTableWidget中的项由QTableWidgetItem提供。

7.9.3.2 用法示例
例47_qtablewidget,TabelWidget表格(难度:简单),本例使用一个TableWidget,绘制一个表格,同时修改项的标题,在表格里可以直接通过双击进行编辑项里的内容,也可以删除项里的内容等。
在新建例程中不要勾选“Generate form”,默认继承QMainWindow类即可。项目新建完成,如下图。
image014.jpg
在头文件“mainwindow.h”具体代码如下。
  1. mainwindow.h编程后的代码

  2. 1   #ifndef MAINWINDOW_H

  3. 2   #define MAINWINDOW_H

  4. 3

  5. 4   #include <QMainWindow>

  6. 5   #include <QTableWidget>

  7. 6

  8. 7   class MainWindow : public QMainWindow

  9. 8   {

  10. 9       Q_OBJECT

  11. 10

  12. 11  public:

  13. 12      MainWindow(QWidget *parent = nullptr);

  14. 13      ~MainWindow();

  15. 14

  16. 15  private:

  17. 16      /* QTabelWidget表格 */

  18. 17      QTableWidget *tableWidget;

  19. 18

  20. 19      /* QTabelWidgetItem表格数据(项) */

  21. 20      QTableWidgetItem *tableWidgetItem[4];

  22. 21

  23. 22  };

  24. 23  #endif // MAINWINDOW_H
复制代码
在源文件“mainwindow.cpp”具体代码如下。
  1. mainwindow.cpp编程后的代码

  2. 1   #include "mainwindow.h"

  3. 2

  4. 3   MainWindow::MainWindow(QWidget *parent)

  5. 4       : QMainWindow(parent)

  6. 5   {

  7. 6       /* 设置主窗体的大小与位置 */

  8. 7       this->setGeometry(0, 0, 800, 480);

  9. 8      

  10. 9       /* 实例化 */

  11. 10      tableWidget = new QTableWidget(this);

  12. 11      /* 设置tableWidget表居中 */

  13. 12      setCentralWidget(tableWidget);

  14. 13      /* 设置列数 */

  15. 14      tableWidget->setColumnCount(2);

  16. 15      /* 设置行数 */

  17. 16      tableWidget->setRowCount(2);

  18. 17      /* 使用标签设置水平标题标签 */

  19. 18      tableWidget->setHorizontalHeaderLabels(

  20. 19                  QStringList()<<"姓名"<<"性别"

  21. 20                  );

  22. 21     

  23. 22      /* 字符串类型链表 */

  24. 23      QList <QString> strList;

  25. 24      strList<<"小明"<<"小红"<<"男"<<"女";

  26. 25     

  27. 26      for (int i = 0; i < 4; i++) {

  28. 27          /* 实例化 */

  29. 28          tableWidgetItem[i] = new QTableWidgetItem(strList[i]);

  30. 29          /* 设置文本居中对齐 */

  31. 30          tableWidgetItem[i]->setTextAlignment(Qt::AlignCenter);

  32. 31      }

  33. 32      /* 插入数据,表的index就是一个二维数组数据 */

  34. 33      tableWidget->setItem(0, 0, tableWidgetItem[0]);

  35. 34      tableWidget->setItem(1, 0, tableWidgetItem[1]);

  36. 35      tableWidget->setItem(0, 1, tableWidgetItem[2]);

  37. 36      tableWidget->setItem(1, 1, tableWidgetItem[3]);

  38. 37     

  39. 38  }

  40. 39

  41. 40  MainWindow::~MainWindow()

  42. 41  {

  43. 42  }
复制代码
在源文件“main.cpp”具体代码如下。由新建项目时生成,无改动。
  1. main.cpp编程后的代码

  2. 1   #include "mainwindow.h"

  3. 2

  4. 3   #include <QApplication>

  5. 4

  6. 5   int main(int argc, char *argv[])

  7. 6   {

  8. 7       QApplication a(argc, argv);

  9. 8       MainWindow w;

  10. 9       w.show();

  11. 10      return a.exec();

  12. 11  }
复制代码

7.9.3.3 运行效果
程序编译运行的结果如下。双击表格中的项,可修改表格的内容,同时也可以删除内容等。
image016.jpg



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-5-29 03:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表