【QT】QStandardItemModel类的应用介绍

news2024/10/3 2:15:41

目录

1 概述

2 常用方法

3 QStandardItemModel的使用

3.1 界面设计与主窗口类定义

3.2 系统初始化

3.3 从文本文件导入数据

3.4 数据修改

3.5 单元格格式设置

3.6 数据另存为文件

1 概述

        QStandardItemModel是标准的以项数据(itemdata)为基础的标准数据模型类,通常与 QTableView 组合成Model/View结构,实现通用的二维数据的管理功能。
        QStandardItemModel中的项目是由QStandardItem提供的。QStandardItemModel实现了QAbstractItemModel接口,这意味着该模型可用于在支持该接口的任何视图中提供数据(例如QListView、QTableView和QTreeView,以及自定义视图)。为了提高性能和灵活性,可能希望从QAbstractItemModel中派生子类,以提供对不同种类数据存储库的支持。例如,QDirModel提供了对底层文件系统的模型接口。
        本文介绍QStandardItemModel的使用,主要用到以下3个类。
  • QStandardItemModel:基于项数据的标准数据模型,可以处理二维数据。维护一个二维的项数 数组,每个项是一个 QStandardltem 类的变量,用于存储项的数据、字体格式、对齐方式等。
  • QTableView:二维数据表视图组件,有多个行和多个列,每个基本显示单元是一个单元格,通过setModel()函数设置一个QStandardItemModel类的数据模型之后,一个单元格显示QStandardItemModel数据模型中的一个项。
  • QItemSelectionModel:一个用于跟踪视图组件的单元格选择状态的类,当在QTableView选择某个单元格,或多个单元格时,通过QItemSelectionModel可以获得选中的单元格的 模型索引,为单元格的选择操作提供方便。
         这几个类之间的关系是:QTableView是界面视图组件,其关联的数据模型是QStandardItem
Model,关联的项选择模型是QItemSelectionModel,QStandardItemModel的数据管理的基本单元是 QStandardItem。
        当想要一个列表或树时,通常会创建一个空的QStandardItemModel,并使用appendRow()将项目添加到模型中,并使用item()访问项目。如果模型表示一个表格,则通常会将表格的尺寸传递给QStandardItemModel构造函数,并使用setItem()将项目定位到表格中。还可以使用setRowCount()和setColumnCount()来更改模型的尺寸。要插入项目,请使用insertRow()或insertColumn(),要删除项目,请使用removeRow()或removeColumn()。
        此外,可以使用setHorizontalHeaderLabels()和setVerticalHeaderLabels()设置模型的标题标签。可以使用findItems()搜索模型中的项目,并通过调用sort()对模型进行排序。调用clear()可以从模型中删除所有项目。
示例:创建树
  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;
  }
 示例:创建表格
  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);
      }
  }

        在将模型设置到视图上之后,通常希望对用户操作做出反应,例如单击一个项目。由于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)));
        当接收到信号时,调用给定模型索引上的itemFromIndex()以获取指向该项目的指针:
void MyWidget::clicked(const QModelIndex &index)
  {
      QStandardItem *item = myStandardItemModel->itemFromIndex(index);
  }
        反之,在希望调用以索引为参数的model/view函数时,必须获取项目的QModelIndex。可以使用模型的indexFromItem()函数或等效地调用QStandardItem::index()来获取索引:
treeView->scrollTo(item->index());
        当然,并不需要使用基于项目的方法;在处理模型时,也可以完全依赖于QAbstractItemModel接口,或者根据需要使用两者的组合。

2 常用方法

  • void QStandardItemModel::appendColumn(const QList<QStandardItem *> &items):
          添加一个包含项目的列。如果必要,行数将增加到items的大小。
  • void QStandardItemModel::appendRow(const QList<QStandardItem *> &items): 
        添加一个包含项目的行。如果必要,列数将增加到items的大小。
  • void QStandardItemModel::appendRow(QStandardItem *item):
        这是一个重载函数。当构建仅有一列的列表或树时,此函数提供了一种方便的方法来追加新项目。
  • void QStandardItemModel::clear():
        从模型中删除所有项目(包括标题项目),并将行数和列数设置为零。
  • [virtual] int QStandardItemModel::columnCount(const QModelIndex &parent = QModelIndex()) const:
        从QAbstractItemModel::columnCount()函数中重新实现。
  • [virtual] QVariant QStandardItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const:
        从QAbstractItemModel::data()函数中重新实现。
  • [virtual] bool QStandardItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent):
        从QAbstractItemModel::dropMimeData()函数中重新实现。
  • QList<QStandardItem *> QStandardItemModel::findItems(const QString &text, Qt::MatchFlags flags = Qt::MatchExactly, int column = 0) const:
        返回与给定文本匹配的项目列表,使用给定标志,在给定列中。
  • [virtual] Qt::ItemFlags QStandardItemModel::flags(const QModelIndex &index) const:
        从QAbstractItemModel::flags()函数中重新实现。
  • [virtual] bool QStandardItemModel::hasChildren(const QModelIndex &parent = QModelIndex()) const:
        从QAbstractItemModel::hasChildren()函数中重新实现。
  • [virtual] QVariant QStandardItemModel::headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const:
        从QAbstractItemModel::headerData()函数中重新实现。
  • QStandardItem *QStandardItemModel::horizontalHeaderItem(int column) const:
        如果已设置,则返回列的水平标题项;否则返回0。
  • [virtual] QModelIndex QStandardItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const:
        从QAbstractItemModel::index()函数中重新实现。
  • QModelIndex QStandardItemModel::indexFromItem(const QStandardItem *item) const:
       返回与给定项关联的QModelIndex。在执行需要项的QModelIndex的操作(例如QAbstractItemView :: scrollTo())时,请使用此函数。QStandardItem :: index()提供了方便性; 它相当于调用此函数。
  • void QStandardItemModel::insertColumn(int column, const QList<QStandardItem *> &items):
        在包含项的column处插入一个列。如果必要,行数将增加到items的大小。
  • bool QStandardItemModel::insertColumn(int column, const QModelIndex &parent = QModelIndex()):
        在父项的子项中在给定列之前插入单个列。如果插入列,则返回true; 否则返回false。
  • [virtual] bool QStandardItemModel::insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()):从QAbstractItemModel :: insertColumns()函数中重新实现。
  • void QStandardItemModel::insertRow(int row, const QList<QStandardItem *> &items):
        在包含项的row处插入一个行。如果必要,列数将增加到items的大小。
  • void QStandardItemModel::insertRow(int row, QStandardItem *item):
        这是一个重载函数。在包含项的row处插入一个包含单个项的行。当构建仅有一列的列表或树时,此函数提供了一种方便的方法来追加一个新项。
  • bool QStandardItemModel::insertRow(int row, const QModelIndex &parent = QModelIndex()):
        在父项的子项中在给定行之前插入单个行。如果插入行,则返回true; 否则返回false。
  • [virtual] bool QStandardItemModel::insertRows(int row, int count, const QModelIndex &parent = QModelIndex()):
        从QAbstractItemModel :: insertRows()函数中重新实现。
  • QStandardItem *QStandardItemModel::invisibleRootItem() const:
        返回模型的不可见根项。不可见的根项通过QStandardItem API提供对模型的顶级项的访问,使得可以编写可以以统一的方式处理顶级项和它们的子项的函数;例如,涉及树模型的递归函数。注意:对从此函数检索的QStandardItem对象调用index()无效。
  • QStandardItem *QStandardItemModel::item(int row, int column = 0) const:
        如果已设置,则返回给定行和列的项; 否则返回0。
  • [signal] void QStandardItemModel :: itemChanged(QStandardItem *item):
        每当item的数据更改时,就会发射此信号。
  • [virtual] QMap<int,QVariant> QStandardItemModel :: itemData(const QModelIndex &index) const:
        从QAbstractItemModel :: itemData()函数中重新实现。
  • QStandardItem *QStandardItemModel::itemFromIndex(const QModelIndex &index) const:
        返回与给定索引关联的QStandardItem的指针。
         在处理基于QModelIndex的视图信号(例如QAbstractItemView :: activated())时,通常调用此函数是初始步骤。在您的槽中,使用由信号携带的QModelIndex调用itemFromIndex()以获取指向相应QStandardItem的指针。
注意,如果在该索引处不存在项,则此函数将延迟创建该项(使用itemPrototype()),并将其设置在父项的子项表格中。
如果index是无效索引,则此函数返回0。
  • const QStandardItem *QStandardItemModel::itemPrototype() const:
        返回模型使用的项原型。当需要按需构建新项(例如,当视图或项代理调用setData())时,模型使用项原型作为项工厂。
  • [virtual] QMimeData *QStandardItemModel :: mimeData(const QModelIndexList &indexes) const:
        从QAbstractItemModel :: mimeData()函数中重新实现。
  • [virtual] QStringList QStandardItemModel :: mimeTypes() const:
        从QAbstractItemModel :: mimeTypes()函数中重新实现。
  • [virtual] QModelIndex QStandardItemModel::parent(const QModelIndex &child) const:
        从QAbstractItemModel :: parent()函数中重新实现。
  • [virtual] bool QStandardItemModel::removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()):
        从QAbstractItemModel :: removeColumns()函数中重新实现。
  • [virtual] bool QStandardItemModel::removeRows(int row, int count, const QModelIndex &parent = QModelIndex()):
        从QAbstractItemModel :: removeRows()函数中重新实现。
  • [virtual] int QStandardItemModel::rowCount(const QModelIndex &parent = QModelIndex()) const:
        从QAbstractItemModel :: rowCount()函数中重新实现。
  • void QStandardItemModel::setColumnCount(int columns):
        将模型中的列数设置为columns。如果这小于columnCount(),则舍弃不需要的列中的数据。
  • [virtual] bool QStandardItemModel::setData(const QModelIndex &index,const QVariant &value,int role = Qt :: EditRole):
        从QAbstractItemModel :: setData()函数中重新实现。
  • [virtual] bool QStandardItemModel::setHeaderData(int section,Qt :: Orientation orientation,const QVariant &value,int role = Qt :: EditRole):
        从QAbstractItemModel :: setHeaderData()函数中重新实现。
  • void QStandardItemModel::setHorizontalHeaderItem(int column,QStandardItem *item):
        将列column的水平标头项设置为item。模型接管该项。必要时,列计数将增加以适应该项。删除先前的标头项(如果有任何)。
  • void QStandardItemModel::setHorizontalHeaderLabels(const QStringList &labels):
        使用labels设置水平标头标签。如果必要,列计数将增加到labels的大小。
  • void QStandardItemModel::setItem(int row,int column,QStandardItem *item):
        将给定行和列的项设置为item。模型接管该项。必要时,行计数和列计数将增加以适应该项。删除给定位置的先前项(如果有任何)。
  • void QStandardItemModel::setItem(int row,QStandardItem *item):
        这是一个重载函数。
  • [virtual] bool QStandardItemModel::setItemData(const QModelIndex &index,const QMap <int,QVariant> &roles):
        从QAbstractItemModel :: setItemData()函数中重新实现。
  • void QStandardItemModel::setItemPrototype(const QStandardItem *item):
        将该模型的项原型设置为指定的项。模型接管原型。
        项原型通过依赖于QStandardItem :: clone()函数来作为QStandardItem工厂。要提供自己的原型,请子类化QStandardItem,重新实现QStandardItem :: clone()并将原型设置为您自定义类的实例。每当QStandardItemModel需要按需创建项(例如,当视图或项代理调用setData())时,新项将是您自定义类的实例。
  • void QStandardItemModel::setItemRoleNames(const QHash<int,QByteArray> &roleNames):
        将项角色名称设置为roleNames。
  • void QStandardItemModel::setRowCount(int rows):
        将模型中的行数设置为rows。如果这小于rowCount(),则舍弃不需要的行中的数据。
  • void QStandardItemModel::setVerticalHeaderItem(int row,QStandardItem *item):
        将行row的垂直标头项设置为item。模型接管该项。必要时,行计数将增加以适应该项。删除先前的标头项(如果有任何)。
  • void QStandardItemModel::setVerticalHeaderLabels(const QStringList &labels):
        使用labels设置垂直标头标签。如果必要,行计数将增加到labels的大小。
  • [virtual] QModelIndex QStandardItemModel::sibling(int row,int column,const QModelIndex &idx) const:
        从QAbstractItemModel :: sibling()函数中重新实现。
  • [virtual] void QStandardItemModel::sort(int column,Qt :: SortOrder order = Qt :: AscendingOrder):
        从QAbstractItemModel :: sort()函数中重新实现。
  • [virtual] Qt :: DropActions QStandardItemModel :: supportedDropActions() const:
        从QAbstractItemModel :: supportedDropActions()函数中重新实现。
        QStandardItemModel支持复制和移动。
  • QList<QStandardItem *> QStandardItemModel::takeColumn(int column):
        删除给定的列而不删除列项,并返回指向已删除项的指针列表。模型释放项的所有权。对于未设置的列中的项,列表中相应的指针将为0。
  • QStandardItem *QStandardItemModel::takeHorizontalHeaderItem(int column):
        从标头中删除列column的水平标头项而不删除它,并返回指向该项的指针。模型释放项的所有权。
  • QStandardItem *QStandardItemModel::takeItem(int row,int column = 0):
        删除(行,列)处的项而不删除它。模型释放项的所有权。
  • QList<QStandardItem *> QStandardItemModel::takeRow(int row):
        删除给定的行而不删除行项,并返回指向已删除项的指针列表。模型释放项的所有权。对于未设置的行中的项,列表中相应的指针将为0。
  • QStandardItem *QStandardItemModel::takeVerticalHeaderItem(int row):
        从标头中删除行row的垂直标头项而不删除它,并返回指向该项的指针。模型释放项的所有权。
  • QStandardItem *QStandardItemModel :: verticalHeaderItem(int row) const:
        如果已设置,则返回行row的垂直标头项;否则返回0。

QStandardItemModel的使用

        实例samp5_3演示QStandardltemModel的使用,实例samp5_3的运行时界面如图所示, 该实例具有如下功能。
  • 打开一个纯文本文件,该文件是规则的二维数据文件,通过字符串处理获取表头和各行各 列的数据,导入到一个QStandardItemModel数据模型。
  • 编辑修改数据模型的数据,可以插入行、添加行、删除行,还可以在QTableView视图组 件中直接修改单元格的数据内容。
  • 可以设置数据模型中某个项的不同角色的数据,包括文字对齐方式、字体是否粗体等。
  • 通过QItemSelectionModel获取视图组件上的当前单元格,以及选择单元格的范围,对选 择的单元格进行操作。
  • 将数据模型的数据内容显示到QPlainTextEdit组件里,显示数据模型的内容,检验视图组 件上做的修改是否与数据模型同步。
  • 将修改后的模型数据另存为一个文本文件。

3.1 界面设计与主窗口类定义

        本实例的主窗口从QMainWindow继承而来,中间的TableView和PlainTextEdit组件采用水平 分割条布局。在Action编辑器中创建如图所示的一些Action,并由Action创建主工具栏上的 按钮,下方的状态栏设置了几个QLabel组件,显示当前文件名称、当前单元格行号、列号,以及 相应内容。
主窗口类MainWindow里新增的定义如下:
class MainWindow : public QMainWindow
{
    Q_OBJECT
private:

//用于状态栏的信息显示
    QLabel  *LabCurFile;  //当前文件
    QLabel  *LabCellPos;    //当前单元格行列号
    QLabel  *LabCellText;   //当前单元格内容
    QStandardItemModel  *theModel;//数据模型
    QItemSelectionModel *theSelection;//Item选择模型
    void    iniModelFromStringList(QStringList&);//从StringList初始化数据模型
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
//当前选择单元格发生变化
    void on_currentChanged(const QModelIndex &current, const QModelIndex &previous);

    void on_actOpen_triggered(); //打开文件

    void on_actAppend_triggered(); //添加行

    void on_actInsert_triggered();//插入行

    void on_actDelete_triggered();//删除行

    void on_actModelData_triggered();  //导出模型数据

    void on_actSave_triggered();//保存文件

    void on_actAlignCenter_triggered();//居中对齐

    void on_actFontBold_triggered(bool checked);//粗体字体

    void on_actAlignLeft_triggered(); //居左对齐

    void on_actAlignRight_triggered();//居右对齐
private:
    Ui::MainWindow *ui;
};

    这里定义了数据模型变量theModel,项数据选择模型变量theSelection。

        定义的私有函数iniModelFromStringList()用于在打开文件时,从一个QStringList变量的内容创建数据模型。

        自定义槽函数oncurrentChanged()用于在TableView上选择单元格发生变化时,更新状态栏的信息显示,这个槽函数将会与项选择模型theSelection的currentChanged()信号关联。

3.2 系统初始化

在MainWindow的构造函数中进行界面初始化,数据模型和选择模型的创建,以及与视图组

件的关联,信号与槽的关联等设置,代码如下:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    theModel = new QStandardItemModel(2,FixedColumnCount,this); //数据模型
    theSelection = new QItemSelectionModel(theModel);//Item选择模型

//选择当前单元格变化时的信号与槽
    connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),
            this,SLOT(on_currentChanged(QModelIndex,QModelIndex)))
    //为tableView设置数据模型
    ui->tableView->setModel(theModel); //设置数据模型
    ui->tableView->setSelectionModel(theSelection);//设置选择模型
    ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
    setCentralWidget(ui->splitter); 
//创建状态栏组件
...
}

在构造函数里首先创建数据模型theModel,创建数据选择模型时需要传递一个数据模型变量

作为其参数。这样,数据选择模型theSelection就与数据模型theModeI关联,用于表示theModel

的项数据选择操作。

创建数据模型和选择模型后,为TableView组件设置数据模型和选择模型:

theModel = new QStandardItemModel(2,FixedColumnCount,this); //数据模型

theSelection = new QItemSelectionModel(theModel);//Item选择模型

构造函数里还将自定义的槽函数oncurrentChanged()与theSelection的currentChanged()信号关

联,用于界面上tableView选择单元格发生变化时,显示单元格的行号、列号、内容等信息,槽函

数代码如下:

void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)

{ //选择单元格变化时的响应

    if (current.isValid()) //当前模型索引有效

    {

        LabCellPos->setText(QString::asprintf("当前单元格:%d行,%d列",

                                  current.row(),current.column())); //显示模型索引的行和列号

        QStandardItem   *aItem;

        aItem=theModel->itemFromIndex(current); //从模型索引获得Item

        this->LabCellText->setText("单元格内容:"+aItem->text()); //显示item的文字内容

        QFont   font=aItem->font(); //获取item的字体

        ui->actFontBold->setChecked(font.bold()); //更新actFontBold的check状态

    }

}

3.3 从文本文件导入数据

        QStandardItemModel是标准的基于项数据的数据模型,以类似于二维数组的形式管理内部数据,适合于处理表格型数据,其显示一般采用QTableView。

        QStandardItemModel的数据可以是程序生成的内存中的数据,也可以来源于文件。例如,在实际数据处理中,有些数据经常是以纯文本格式保存的,它们有固定的列数,每一列是一项数据,实际构成一个二维数据表。图1是本实例程序要打开的一个纯文本文件的内容,文件的第1行

是数据列的文字标题,相当于数据表的表头,然后以行存储数据,以TAB键间隔每列数据。

        当单击工具栏上的“打开文件”按钮时,需要选择一个这样的文件导入到数据模型,并在tableView上进行显示和编辑。图1的数据有6列,第1列是整数,第2至4列是浮点数,第5列是文字,第6列是逻辑型变量,“1”表示true。

图1 纯文本格式的数据文件

下面是“打开文件”按钮的槽函数代码:

void MainWindow::on_actOpen_triggered()
{ //打开文件
    QString curPath=QCoreApplication::applicationDirPath(); //获取应用程序的路径
//调用打开文件对话框打开一个文件
    QString aFileName=QFileDialog::getOpenFileName(this,"打开一个文件",curPath,
                 "井数据文件(*.txt);;所有文件(*.*)");
    if (aFileName.isEmpty())
        return; //如果未选择文件,退出

    QStringList fFileContent;//文件内容字符串列表
    QFile aFile(aFileName);  //以文件方式读出
    if (aFile.open(QIODevice::ReadOnly | QIODevice::Text)) //以只读文本方式打开文件
    {
        QTextStream aStream(&aFile); //用文本流读取文件
        ui->plainTextEdit->clear();//清空
        while (!aStream.atEnd())
        {
            QString str=aStream.readLine();//读取文件的一行
            ui->plainTextEdit->appendPlainText(str); //添加到文本框显示
            fFileContent.append(str); //添加到 StringList
        }
        aFile.close();//关闭文件

        this->LabCurFile->setText("当前文件:"+aFileName);//状态栏显示
        ui->actAppend->setEnabled(true); //更新Actions的enable属性
        ui->actInsert->setEnabled(true);
        ui->actDelete->setEnabled(true);
        ui->actSave->setEnabled(true);

        iniModelFromStringList(fFileContent);//从StringList的内容初始化数据模型
    }
}
 在逐行获取字符串后,也采用split()函数进行分解,为每个数据创建一个QStandardItem 类型的项数据altem,并赋给数据模型作为某行某列的项数据。
        QStandardItemModel以二维表格的形式保存项数据,每个项数据对应着QTableView的一个单 元格。项数据不仅可以存储显示的文字,还可以存储其他角色的数据。
        数据文件的最后一列是一个逻辑型数据,在tableView上显示时为其提供一个CheckBox组件, 此功能通过调用QStandardItem的setCheckable()函数实现。

3.4 数据修改

        当TableView设置为可编辑时,双击一个单元格可以修改其内容,对于使用CheckBox的列, 改变CheckBox的勾选状态,就可以修改单元格关联项的选择状态。
        在实例主窗口工具栏上有“添加行”“插入行”“删除行”按钮,它们实现相应的编辑操作, 这些操作都是直接针对数据模型的,数据模型被修改后,会直接在上显示出来。
  • 添加行

void MainWindow::on_actAppend_triggered()
{ //在表格最后添加行
    QList<QStandardItem*>    aItemList; //容器类
    QStandardItem   *aItem;   //数据管理的基本单元
    for(int i=0;i<FixedColumnCount-1;i++) //不包含最后1列
    {
        aItem=new QStandardItem("0"); //创建Item
        aItemList<<aItem;   //添加到容器
    }
//获取最后一列的表头文字
    QString str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
    aItem=new QStandardItem(str); //创建 "测井取样"Item
    aItem->setCheckable(true);
    aItemList<<aItem;   //添加到容器

    theModel->insertRow(theModel->rowCount(),aItemList); //插入一行,需要每个Cell的Item
    QModelIndex curIndex=theModel->index(theModel->rowCount()-1,0);//创建最后一行的ModelIndex
    theSelection->clearSelection();//清空选择项
    theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);//设置刚插入的行为当前选择行
}
  • 插入行

void MainWindow::on_actInsert_triggered()
{//插入行
    QList<QStandardItem*>    aItemList;  //QStandardItem的列表类
    QStandardItem   *aItem;
    for(int i=0;i<FixedColumnCount-1;i++)
    {
        aItem=new QStandardItem("0"); //新建一个QStandardItem
        aItemList<<aItem;//添加到列表类
    }
    QString str;    //获取表头文字
    str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
    aItem=new QStandardItem(str); //创建Item
    aItem->setCheckable(true);//设置为可使用CheckBox
    aItemList<<aItem;//添加到列表类
    QModelIndex curIndex=theSelection->currentIndex(); //获取当前选中项的模型索引
    theModel->insertRow(curIndex.row(),aItemList);  //在当前行的前面插入一行
    theSelection->clearSelection();//清除已有选择
    theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
}
  • 删除行

void MainWindow::on_actDelete_triggered()
{ //删除行
    QModelIndex curIndex=theSelection->currentIndex();//获取当前选择单元格的模型索引
    if (curIndex.row()==theModel->rowCount()-1)//最后一行
        theModel->removeRow(curIndex.row()); //删除最后一行
    else
    {
       theModel->removeRow(curIndex.row());//删除一行,并重新设置当前选择行
       theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
    }
}

3.5 单元格格式设置

void MainWindow::on_actAlignCenter_triggered()
{//文字居中对齐
    if (!theSelection->hasSelection())
        return;
    QModelIndexList selectedIndex=theSelection->selectedIndexes()

    QModelIndex aIndex;
    QStandardItem   *aItem;
    for (int i=0;i<selectedIndex.count();i++)
    {
        aIndex=selectedIndex.at(i);
        aItem=theModel->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignHCenter);
    }
}

void MainWindow::on_actFontBold_triggered(bool checked)
{//设置字体粗体
    if (!theSelection->hasSelection())
        return;
//获取选择单元格的模型索引列表
    QModelIndexList selectedIndex=theSelection->selectedIndexes();
    for (int i=0;i<selectedIndex.count();i++)
    {
        QModelIndex aIndex=selectedIndex.at(i); //获取一个模型索引
        QStandardItem* aItem=theModel->itemFromIndex(aIndex);//获取项数据
        QFont font=aItem->font(); //获取字体
        font.setBold(checked); //设置字体是否粗体
        aItem->setFont(font); //重新设置字体
    }
}

3.6 数据另存为文件

        在视图组件上对数据的修改都会自动更新到数据模型里,单击工具栏上的“模型数据预览”按钮,可以将数据模型的数据内容显示到PlainTextEdit里。

        数据模型里的数据是在内存中的,工具栏上的“另存文件”按钮可以将数据模型的数据另存为一个数据文本文件,同时也显示在PlainTextEdit里,其实现代码如下:

void MainWindow::on_actSave_triggered()
{ //保存为文件
    QString curPath=QCoreApplication::applicationDirPath(); //获取应用程序的路径
//调用打开文件对话框选择一个文件
    QString aFileName=QFileDialog::getSaveFileName(this,tr("选择一个文件"),curPath,
                 "井斜数据文件(*.txt);;所有文件(*.*)");

    if (aFileName.isEmpty()) //未选择文件,退出
        return;

    QFile aFile(aFileName);
    if (!(aFile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)))
        return; //以读写、覆盖原有内容方式打开文件

    QTextStream aStream(&aFile); //用文本流读取文件

    QStandardItem   *aItem;
    int i,j;
    QString str;

    ui->plainTextEdit->clear();

//获取表头文字
    for (i=0;i<theModel->columnCount();i++)
    {
        aItem=theModel->horizontalHeaderItem(i); //获取表头的项数据
        str=str+aItem->text()+"\t\t";  //以TAB见隔开
    }
    aStream<<str<<"\n";  //文件里需要加入换行符 \n
    ui->plainTextEdit->appendPlainText(str);

//获取数据区文字
    for ( i=0;i<theModel->rowCount();i++)
    {
        str="";
        for( j=0;j<theModel->columnCount()-1;j++)
        {
            aItem=theModel->item(i,j);
            str=str+aItem->text()+QString::asprintf("\t\t");
        }

        aItem=theModel->item(i,j); //最后一列是逻辑型
        if (aItem->checkState()==Qt::Checked)
            str=str+"1";
        else
            str=str+"0";

         ui->plainTextEdit->appendPlainText(str);
         aStream<<str<<"\n";
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1362136.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BMS电池管理系统带充放电控制过流过压保护

2.4G无线采集BMS开发板&#xff08;主从一体&#xff09; 全新升级 &#xff08;赠送上位机源码TTL 上位机&#xff0c;可以改成自己想要的界面&#xff09; 12串电池TTL上位机 CAN通信上位机源码有偿开源&#xff0c;供项目二次开发。 增加STM32平台 USB转TTL通信 CAN通信 增加…

Mac启动时候出现禁止符号

Mac启动时候出现禁止符号 启动时候出现禁止符号,意味着 选定的启动磁盘 包含 Mac 操作系统&#xff0c;但它不是 您的 Mac 可以使用的 macOS 。您应该在这个磁盘上 重新安装 macOS 。 可以尝试以下苹果提供的方法&#xff1a; Mac启动时候出现禁止符号 不要轻易抹除磁盘&am…

云原生学习系列之基础环境准备(单节点安装kubernetes)

一、环境要求 操作系统CentOS 7.x-86_x64 硬件配置&#xff1a;内存2GB或2G&#xff0c;CPU 2核或CPU 2核&#xff0c;需要在虚拟机中提前设置好&#xff0c;不然后续会报错 二、系统初始化 1、设置主机名 # 在master节点执行 hostnamectl set-hostname master01 2、配置主…

CRM如何精确控制RT设备和与UMD通信笔记

1 CRM工作职责 监控link req是否得到schedule监控link上各个device的req是否ready监控SOF或EOF的trigger信号&#xff0c;决定各个设备配置哪个req 2 CRM如何精确控制RT设备 分两步&#xff0c;一是crm知道某帧req的link dev准备好了&#xff0c;可以做apply setting。 二是…

解决vue3中watch 监听不到旧值的问题,亲测有效!

问题描述 这个问题是我在公司vue3项目的时候发现的一个问题&#xff0c;watch 在监听对象/数组变量的变化时&#xff0c;发现对象的数据变化时 旧数据 获取到的和新数据是一样的 类似于下面这样 const objref({a:我是原来的值,b:6, })obj.a改变值watch(obj,(nel,old)>{ c…

RTT打印时间戳

官方的RTT VIEWER没有打印接收时间戳的功能&#xff0c;经过查找后发现可以有以下三种打印时间戳的方法。 第三方的RTT上位机ExtraPutty自己打印 第三方的RTT上位机 码云上有一个RTT_T2的仓库&#xff0c;基于python qt包写的画面&#xff0c;通过pylink来jlink通信。 优点…

docker - 常用容器部署命令大全(MySQL、Redis、RabbitMQ、ES、Kibana、Nacos、Sentinel)

目录 一、常用容器运行指令 MySQL Redis RabbitMQ ElasticSearch & kibana Nacos Sentinel 一、常用容器运行指令 MySQL docker run -d --name mysql -p 3306:3306 -e TZAsia/Shanghai -e MYSQL_ROOT_PASSWORD1111 mysql:5.7 -e TZAsia/Shanghai&#xff1a;指定…

商智C店H5性能优化实战

前言 商智C店&#xff0c;是依托移动低码能力搭建的一个应用&#xff0c;产品面向B端商家。随着应用体量持续增大&#xff0c;考虑产品定位及用户体验&#xff0c;我们针对性能较差页面做了一次优化&#xff0c;并取得了不错的效果&#xff0c;用户体验值&#xff08;UEI&…

“智慧”千里眼助力水泵站

泵站是为水提供势能和压能&#xff0c;解决无自流条件下的排灌、供水和水资源调配问题的唯一动力来源&#xff0c;在工农业用水、防洪、排涝和抗旱减灾等方面发挥着重要作用。一旦出现异常&#xff0c;对经济生产将造成难以估量的损失&#xff0c;给水利安全管理造成负担。因此…

VMware Tools 启动脚本未能在虚拟机中成功运行。如果您在此虚拟机中配置了自定义启动脚本,请确保该脚本没有错误。您也可以提交支持请求,报告此问题。

问题描述&#xff1a;今天打开centos7虚拟机就是直接打不开了报了下面的错误&#xff0c;也没有动任何东西&#xff0c;点确定后&#xff0c;也是依然没有反应 问题原因&#xff1a;可能是虚拟机中的内存满了&#xff0c;需要清理内存 解决方法如下 首先cmd打开终端敲入如下命…

【linux笔记】top、ps

【linux笔记】top命令 top&#xff08;Table of process&#xff09;是动态变化的。而ps是静态的。 PID — 进程id USER — 进程所有者 PR — 进程优先级 NI — nice值。负值表示高优先级&#xff0c;正值表示低优先级 VIRT — 进程使用的虚拟内存总量&#xff0c;单位kb。VI…

软件测试|深入学习 Docker Logs

简介 Docker 是一种流行的容器化技术&#xff0c;它能够帮助用户将应用程序及其依赖项打包成一个可移植的容器。Docker logs 是 Docker 提供的用于管理容器日志的命令&#xff0c;本文将深入学习 Docker logs 的使用和管理&#xff0c;帮助用户更好地监测和解决容器问题。 Do…

ArkTS - 网络请求

一、Axios请求 应用通过HTTP发起一个数据请求&#xff0c;支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。 前端开发肯定都使用过一个叫axios的第三方库&#xff0c;它是是一个基于 promise 的网络请求库&#xff0c;可以用于浏览器和 node.js&…

网络实训模拟考察题目和答案(华为eNSP综合实验考试)

拓扑中四个交换机五个路由器&#xff0c;共九个设备 答案是对应的九个脚本&#xff08;从设备命名到保存&#xff09; 全部复制粘贴后&#xff0c;从PC1、PC2都是能Ping通服务器的&#xff08;保及格&#xff09;&#xff0c;其他要求没检查 题目 VLAN信息 设备名称端口链路…

labview 与三菱FX 小型PLC通信(OPC)

NI OPC服务器与三菱FX3U PLC通讯方法 一、新建通道名称为&#xff1a;MIT 二、选择三菱FX系列 三、确认端口号相关的参数&#xff08;COM端&#xff1a;7.波特率&#xff1a;9600&#xff0c;数据位&#xff1a;7&#xff0c;校验&#xff1a;奇校验&#xff0c;停止位&#xf…

js中函数动态调用

文章目录 一、场景二、方法2.1、动态函数2.2、eval()函数 三、最后 一、场景 在JS开发中&#xff0c;例如有些场景下&#xff0c;后端要求一个功能要请求不同的接口&#xff0c;但是传参及后续逻辑其实都是一样的&#xff0c;有些同学可能会想到在接口url处统一处理就好&#…

开关电源启动电路图

1、常规启动电路 常规启动电路的电路形式如图 接通电源开关后&#xff0c;市电电压经整流、滤波后&#xff0c;获得约300V的直流电压&#xff0c;一路经开关变压器的一次绕组送到开关管的漏极&#xff1b;另一路经R1、R2对C1进行充电&#xff0c;当C1两端电压达到一定值时&…

ES -极客学习

Elasticsearch 简介及其发展历史 起源 Lucene 于 Java 语言开发的搜索引擎库类创建于 1999 年&#xff0c;2005 年成为 Apache 顶级开源项目Lucene 具有高性能、易扩展的优点Lucene 的局限性 只能基于 Java 语言开发类库的接口学习曲线陡峭原生并不支持水平扩展原生并不支持水…

Swift爬虫使用代理IP采集唯品会商品详情

目录 一、准备工作 二、代理IP的选择与使用 三、使用Swift编写唯品会商品爬虫 四、数据解析与处理 五、注意事项与优化建议 六、总结 一、准备工作 在开始编写爬虫之前&#xff0c;需要准备一些工具和库&#xff0c;以确保数据抓取的顺利进行。以下是所需的工具和库&…

每日一题——LeetCode1089.复写0

方法一 splice&#xff1a; 通过数组的slice方法&#xff0c;碰到 0就在后面加一个0&#xff0c;最后截取原数组的长度&#xff0c;舍弃后面部分。 但这样做是违反了题目的要求&#xff0c;不要在超过该数组长度的位置写入元素。 var duplicateZeros function(arr) {var le…