• 【Qt之QStandardItemModel】使用,tableview、listview、treeview设置模型


    1. 引入

    QStandardItemModel类提供了一个通用的模型,用于存储自定义数据。
    以下是其用法:该类属于gui模块,因此在.pro中,需添加QT += gui,如果已存在,则无需重复添加。
    首先,引入头文件:

    #include  
    
    • 1

    2. 描述

    以下介绍很重要,可以慢下心来阅读。
    QStandardItemModel类提供了一个用于存储自定义数据的通用模型。
    QStandardItemModel可以用作标准Qt数据类型的存储库。它是模型/视图类之一,是Qt模型/视图框架的一部分。
    QStandardItemModel提供了一种经典的基于项目的方法来处理模型。QStandardItemModel中的项由QStandardItem提供。
    QStandardItemModel实现了QAbstractItemModel接口,这意味着该模型可以用于在任何支持该接口的视图中提供数据(例如QListView, QTableViewQTreeView,以及您自己的自定义视图)。为了提高性能和灵活性,您可能希望创建QAbstractItemModel的子类,以便为不同类型的数据存储库提供支持。例如,QDirModel为底层文件系统提供了一个模型接口。
    当您需要一个列表或树时,您通常会创建一个空的QStandardItemModel,并使用appendRow()向模型中添加项目,并使用item()访问项目。如果您的模型表示一个表,您通常将表的尺寸传递给QStandardItemModel构造函数,并使用setItem()将项目定位到表中。您还可以使用setRowCount()setColumnCount()来更改模型的尺寸。要插入项,使用insertRow()insertColumn(),要删除项,使用removeRow()removeColumn()
    您可以使用setHorizontalHeaderLabels()setVerticalHeaderLabels()设置模型的标题标签。
    您可以使用findItems()在模型中搜索项目,并通过调用sort()对模型进行排序。
    调用clear()从模型中删除所有项。
    QStandardItemModel创建表的一个示例:

      QStandardItemModel model(4, 4);
      for (int row = 0; row < 4; ++row) {
          for (int column = 0; column < 4; ++column) {
              QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
              model.setItem(row, column, item);
          }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    QStandardItemModel创建树的一个例子:

      QStandardItemModel model;
      QStandardItem *parentItem = model.invisibleRootItem();
      for (int i = 0; i < 4; ++i) {
          QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
          parentItem->appendRow(item);
          parentItem = item;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在视图上设置模型之后,您通常希望对用户操作做出反应,例如单击项。由于QAbstractItemView提供了基于QModelIndex的信号和函数,您需要一种方法来获得与给定的QModelIndex相对应的QStandardItem,反之亦然。itemFromIndex()indexFromItem()提供了这种映射。itemFromIndex()的典型用法包括获取视图中当前索引处的项,以及获取与QAbstractItemView信号携带的索引对应的项,例如QAbstractItemView::clicked()。首先,你将视图的信号连接到类中的槽:

      QTreeView *treeView = new QTreeView(this);
      treeView->setModel(myStandardItemModel);
      connect(treeView, SIGNAL(clicked(QModelIndex)),
              this, SLOT(clicked(QModelIndex)));
    
    • 1
    • 2
    • 3
    • 4

    当你收到信号时,你调用itemFromIndex()在给定的模型索引上获得一个指向项目的指针:

      void MyWidget::clicked(const QModelIndex &index)
      {
          QStandardItem *item = myStandardItemModel->itemFromIndex(index);
          // Do stuff with the item ...
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    相反,当您想调用以索引作为参数的模型/视图函数时,您必须获得项目的QModelIndex。您可以通过使用模型的indexFromItem()函数或调用QStandardItem::index()来获得索引:

      treeView->scrollTo(item->index());
    
    • 1

    当然,您不需要使用基于项目的方法;在使用模型时,您可以完全依赖于QAbstractItemModel接口,或者使用两者的适当组合。

    常用方法

    1. QStandardItemModel::QStandardItemModel(QObject *parent = Q_NULLPTR)
      构造一个带有给定父对象的新项模型。

    2. QStandardItemModel::QStandardItemModel(int rows, int columns, QObject *parent = Q_NULLPTR)
      构造一个初始具有rows行和columns列的新项模型,并给它指定一个父对象。

    3. QStandardItemModel::~QStandardItemModel()
      销毁模型。模型会销毁所有的项。

    4. voidStandardItemModel::appendColumn(const QList &items)
      追加一个包含项的列。如果需要,行数将增加到items的大小。

    5. void QStandardItemModel::appendRow(const QList &items)
      追加一个包含项的行。如果需要,列数将增加到items的大小。

    6. void QStandardItemModel::appendRow(QStandardItem *item)
      这是一个重载函数。
      当构建只有一列的列表或树时,此函数提供了一种方便的方法来追加一个新的项。

    7. void QStandardItemModel::clear()
      从模型中移除所有的项(包括标题项),并将行数和列数设为0。

    8. [virtual] int QStandardItemModel::columnCount(const QModelIndex &parent = QModelIndex()) const
      从QAbstractItemModel::columnCount()重新实现。

    9. [virtual] QVariant QStandardItemModel::data(const QModelIndex &index, int role = QtDisplayRole) const
      从QAbstractItemModel::data()重新实现。

    10. [virtual] bool QStandardItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
      从QAbstractItemModel::dropMimeData()重新实现。

    11. QList QStandardItemModel::findItems(const QString &text, Qt::MatchFlags flags = Qt::MatchExactly, int column = 0) const
      返回与给定文本匹配的项列表,使用给定的标志,在给定列中进行搜索。

    12. [virtual] Qt::ItemFlags QStandardItemModel::flags(const QModelIndex &index)
      从QAbstractItemModel::flags()重新实现。

    13. [virtual] bool QStandardItemModel::hasChildren(const QModelIndex &parent = QModelIndex()) const
      从QAbstractItemModel::hasChildren()重新实现。

    14. QVariant QStandardItemModel::headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const
      从QAbstractItemModel::headerData()重新实现。

    15. QStandardItem *QStandardItemModel::horizontalHeaderItem(int column) const
      返回指定列的水平标题项(如果已设置),否则返回。

    16. [virtual] QModelIndex QStandardItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
      从QAbstractItemModel::index()重新实现。

    17. QModelIndex QStandardItemModel::indexFromItem(const QStandardItem *item) const
      返回与给定项关联的QModelIndex。
      在执行需要项的QModelIndex的操作时使用此函数,例如QAbstractItemView::scrollTo()。QStandardItem::index()提供了方便的方式来调用此函数。

    18. void QStandardItemModel::insertColumn(int column, const QList &items)
      在指定列中插入包含项的列。如果需要,行数将增加到items的大小。

    19. bool QStandardItemModel::insertColumn(int column, const QModelIndex &parent = QModelIndex())
      在指定的父项的子项中的指定列之前插入单个列。如果插入列成功则返回true否则返回false。

    20. `[virtual] bool QStandardItemModel::insertColumns(int column, int count, const QModelIndex &parent = QModelIndex())
      从QAbstractItemModel::insertColumns()重新实现。

    21. void QStandardItemModel::insertRow(int row, const QList &items)
      在指定行中插入包含项的行。如果需要,列数将增加到items的大小。

    22. void QStandardItemModel::insertRow(int row, QStandardItem *item)
      这是一个重载函数。
      在指定行中插入包含item的行。
      当构建只有一列的列表或树时,此函数提供了一种方便的方法来追加一个新的项。

    23. bool QStandardItemModel::insertRow(int row, const QModelIndex &parent = QModelIndex())
      在指定的父项的子项中的指定行之前插入单个行。如果插入行成功则返回true,否则返回false。

    24. [virtual] bool QStandardItemModel::insertRows(int row, int count, const QModelIndex &parent = QModelIndex())
      从QAbstractItemModel::insertRows()重新实现。

    25. QStandardItem *QStandardItemModel::invisibleRootItem() const
      返回模型的不可见根项。
      通过QStandardItem API,不可见的根项提供对模型的顶级项的访问,以使得可以以统一的方式处理顶级项及其子项;例如,涉及树模型的递归函数。
      注意:调用从此函数获取的QStandardItem对象上的index()无效。

    26. QStandardItem *QStandardItemModel::item(int row, int column = 0) const
      返回给定行和列的项(如果已设置),否则返回0。

    27. [signal] void QStandardItemModel::itemChanged(QStandardItem *item)
      在项的数据发生更改时发出此信号。

    28. [virtual] QMap QStandardItemModel::itemData(const QModelIndex &index) const
      从QAbstractItemModel::itemData()重新实现。

    29. QStandardItem *QStandardItemModel::itemFromIndex(const QModelIndex &index) const
      返回与给定索引关联的QStandardItem指针。
      在处理来自视图的基于QModelIndex的信号(如QAbstractItemView::activated())时,通常调用此函数是初始步骤。在您的槽中,您调用itemFromIndex(),传入信号携带的QModelIndex作为参数,以获得指向相应QStandardItem的指针。
      注意,如果不存在指定索引处的项,此函数将懒惰地创建一个项(使用itemPrototype()),并在父项的子项表中设置它。
      如果索引无效,则此函数返回0。

    30. const QStandardItem *QStandardItemModel::itemPrototype() const
      返回模型使用的项原型。当模型在需要按需构造新项时(例如,当视图或项代理调用setData()时),模型使用项原型作为项工厂。

    31. [virtual] QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const
      从QAbstractItemModel::mimeData()重新实现。

    32. [virtual] QStringList QStandardItemModel::mimeTypes() const
      从QAbstractItemModel::mimeTypes()重新实现。

    33. [virtual] QModelIndex QStandardItemModel::parent(const QModelIndex &child) const
      从QAbstractItemModel::parent()重新实现。

    34. [virtual] bool QStandardItemModel::removeColumns(int column, int count, const QModelIndex &parent = QModelIndex())
      从QAbstractItemModel::removeColumns()重新实现。

    35. [virtual] bool QStandardItemModel::removeRows(int row, int count, const QModelIndex &parent = QModelIndex())
      从QAbstractItemModel::removeRows()重新实现。

    36. [virtual] int QStandardItemModel::rowCount(const QModelIndex &parent = QModelIndex()) const
      从QAbstractItemModel::rowCount()重新实现。

    37. void QStandardItemModel::setColumnCount(int columns)
      将模型中的列数设置为columns。如果小于columnCount(),则将丢弃不需要的列的数据。

    38. [v] bool QStandardItemModel::setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
      从QAbstractItemModel::setData重新实现。

    39. [virtual] bool QStandardItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariantvalue, int role = Qt::EditRole)
      从QItemModel::setHeaderData重新实现。

    40. void QStandardItemModel::setHorizontalHeaderItem(int column, QStandardItem *item)
      将列column的水平标题项设置为item。模型将拥有该项。需要,将增加数以适应该项。先前的标题项(如果有)将被删除。

    41. void QStandardItemModel::setHeaderLabels(const QStringList &labels)
      使用labels设置水平标题签。如果需要,将增加列数以与标签大小相匹配。

    42. void QStandardItemModel::setItem(int row, int column, QStandardItem *item)
      将给定行和列项设置为item。模型将拥有该项。如果需要,增加行数和列数以适应该项。给定位置先前项(如果有)将被删除。

    43. [virtual bool QStandardItemModel::setItem(const QModelIndex &index, const QMap &roles)
      从QItemModel::setItemData()重新实现。

    44. void QStandardItemModel::setItemPrototype(const QStandardItem *item)
      将型的项原型设置为指定的项。模型将拥有该原型。
      项原型通过依赖QStandardItem::clone()函数来充当QStandardItem工厂。要提供自己的原型子类化QStandardItem,重新实现QStandardItem::clone()并将原设置为您自定义类的实例。每当QStandardItemModel需要按需创建项(例如,当视图或项委托调用setData()时),新项将是您自定义类的实例。

    45. void QStandardItemModelsetItemRoleNames(const QHash, QByteArray> &roleNames)
      将项角色名称设置为roleNames。
      void QStandardItemModel::setRowCount(int rows)
      模型中的行数为rows。如果小于rowCount(),则丢弃不需要的行数据。

    46. void StandardItemModel::setVerticalHeaderItem(int row, QStandardItem *item)
      将行row的垂直标题项设置为item模型将拥有该项。如果需要,将加行数以适应该项。先前的标题项(有)将被删除。

    47. void QStandardItemModel::setHeaderLabels(const QStringList &labels)
      使用labels设置垂直标题标签。如果需要,将增加行数以与标签大小相匹配。

    48. [virtual] QModelIndex QStandardItemModel::sibling(int row, int column, const QModelIndex &idx) const
      从QAbstractItemModel::sibling()重新实现。

    49. [virtual] void QStandardItemModel::sort(int, Qt::SortOrder order = Qt::Order)
      从QAbstractItemModel::sort()重新实现。

    50. [virtual] Qt::DropActions QStandardItemModel::supportedDropActions() const
      从QAbstractItemModel::supportedDropActions()重新实现。
      QStandardItemModel支持复制和移动。

    51. QList QModel::takeColumn(int column)
      移除给定列而不删除列项,并指向删除的项的指针列表。模型释对项的所有权。对于未设置的列中的项,列表中相应指针将为0。

    52. QStandardItem *QStandardItem::takeHorizontalHeaderItem(int column)
      从中移除位于column的水平项而不删除它,并返回该项的指针。模型释放对该项的所有权。

    53. QStandardItem *QStandardItemModel::take(int row, int column =0)
      移除(row,column)位置的项,不删除它。模型释放对该项所有权。

    54. QList QModel::takeRow(int row)
      移除给定行而不删除行项,并返回指向删除的项的指针列表。模型释放对项所有权。对于未设置的行中的项,列表中相应指针将为0。

    55. QStandardItem *QStandardItemModel::takeVerticalHeaderItem(int row)
      从标题中移除位于row的垂直标题项而不删除,并返回该项的指。模型释放对项的所有权。

    56. QStandardItem *QStandardItemModel::verticalHeaderItem(int row) const
      如果已设置,则返回row的垂直标题项;否则0。

    示例

    基于列表模型
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QListView listView;
        QStandardItemModel model;
    
        // 添加行列数据
        QList<QStandardItem *> items;
        items.append(new QStandardItem(QStringLiteral("行1-列1")));
        items.append(new QStandardItem(QStringLiteral("行1-列2")));
        model.appendRow(items);
        items.clear();
        items.append(new QStandardItem(QStringLiteral("行2-列1")));
        items.append(new QStandardItem(QStringLiteral("行2-列2")));
        model.appendRow(items);
    
        // 设置model
        listView.setModel(&model);
    
        // 处理item点击事件
        QObject::connect(&listView, &QListView::clicked, [&](const QModelIndex &index) {
            // 获取点击的item
            QStandardItem *item = model.itemFromIndex(index);
            qDebug() << item->text();
    
            // 将item转换成index
            QModelIndex indexFromItem = model.indexFromItem(item);
    
            // 将index转换成item
            QStandardItem *itemFromIndex = model.itemFromIndex(indexFromItem);
    
            // 设置样式
            itemFromIndex->setBackground(QBrush(QColor(Qt::red)));
        });
    
        listView.show();
    
        return a.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    在这里插入图片描述

    基于树模型
    #include 
    
    int main(int argc, char *argv[]) 
    {
        QApplication app(argc, argv);
    
        // 创建 QTreeView 和 QStandardItemModel
        QTreeView treeView;
        QStandardItemModel model;
        treeView.setModel(&model);
    
        // 创建列标题
        QStringList headerLabels;
        headerLabels << "Name" << "Size" << "Date Modified";
        model.setHorizontalHeaderLabels(headerLabels);
    
        // 添加数据
        QList<QStandardItem *> items;
        items << new QStandardItem("File1.txt") << new QStandardItem("10 KB") << new QStandardItem("2021-01-01");
        model.appendRow(items);
    
        // 获取点击的 item,并将 item 转换为 index 和 item
        QObject::connect(&treeView, &QTreeView::clicked, [&model](const QModelIndex &index){
            QStandardItem *item = model.itemFromIndex(index);
            qDebug() << "Clicked item: " << item->text();
        });
    
        // 设置样式
        QString styleSheet = "QTreeView::item:selected { background-color: yellow; }";
        treeView.setStyleSheet(styleSheet);
    
        // 显示窗口
        treeView.show();
        return app.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在这里插入图片描述

    基于表格模型
    #include 
    #include 
    #include 
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        // 创建模型
        QStandardItemModel model;
        model.setHorizontalHeaderLabels({"Name", "Age", "Gender"});
    
        // 添加数据
        QList<QStandardItem*> rowData;
        rowData << new QStandardItem("John") << new QStandardItem("25") << new QStandardItem("Male");
        model.appendRow(rowData);
        rowData.clear();
        rowData << new QStandardItem("Jane") << new QStandardItem("30") << new QStandardItem("Female");
        model.appendRow(rowData);
    
        // 创建表格视图
        QTableView tableView;
        tableView.setModel(&model);
    
        // 设置样式
        tableView.setStyleSheet("QTableView { border: 1px solid black } QTableView::item { padding: 5px }");
    
        // 获取点击的item
        QObject::connect(&tableView, &QTableView::clicked, [&model](const QModelIndex& index){
            QStandardItem* item = model.itemFromIndex(index);
            if(item) {
                qDebug() << "Clicked item:" << item->text();
            }
        });
        // 当item改变时,触发
        QObject::connect(&model, &QStandardItemModel::itemChanged, [&model](QStandardItem *item){
            // QStandardItem* item = model.itemFromIndex(index);
            if(item) {
                qDebug() << "Changed item:" << item->text();
            }
        });
    
        // 显示表格视图
        tableView.show();
    
        return a.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    在这里插入图片描述

  • 相关阅读:
    new条件构造器的位置很重要
    go环境部署
    使用乐鑫 Web IDE 助力物联网开发
    Tomcat 部署 war 包
    springboot基于Java的电影院售票与管理系统毕业设计源码011449
    C语言进行实验:通过程序实现线算图取值【支持VC++ 6.0编辑器环境运行】
    小程序, 多选项
    Kafka系列之二Docker集群安装运行
    手机快充协议
    前端 富文本编辑器原理——从javascript、html、css开始入门
  • 原文地址:https://blog.csdn.net/MrHHHHHH/article/details/134367312