Qt如何正确的显示、修改表格(QTableView)的内容

    科技2022-07-11  112

    安装Qt时,Qt\Qt5.x.x文件夹下自动安装了example文件夹,其中包含了大量的示例。这里根据Examples\Qt-5.5\widgets\tutorials\modelview\5_edit,制作了一个tableview,支持用户通过表格来编辑条目。

    设计思想:tableview作为界面,QAbstractTableModel作为存储数据的后端。当界面需要显示条目时,会调用QAbstractTableModel::data()函数。此外,QAbstractTableModel::rowCount()和columnnCount()会返回表格的行数(通常也是条目的个数)和列数。假如用户需要在界面上手动修改数据内容,应重写函数QAbstractTableModel::flags()函数。内容被改动后,函数QAbstractTableModel::setData()会被触发。

    代码:

    #pragma once #include <QAbstractTableModel> class EditModel : public QAbstractTableModel { Q_OBJECT public: explicit EditModel(QObject *parent = 0); void vPrint(int); signals: public slots: protected: int rowCount(const QModelIndex &parent) const;//返回模型的行数 int columnCount(const QModelIndex &parent) const;//返回模型的列数 QVariant data(const QModelIndex &index, int role) const;//及时将model内容的变化修改到qtableview中 bool setData(const QModelIndex &index, const QVariant &value, int role) override;//响应手动修改 Qt::ItemFlags flags(const QModelIndex &) const override;//必须有这句,否则无法手动修改模型内容 QList<QPair<QString, QString>> m_lstData; };

     

    #include "EditModel.h" #include <QDebug> EditModel::EditModel(QObject *parent) : QAbstractTableModel(parent) { //m_lstData.reserve(1024);reserve1024个元素并不会使qlist::size() = 1024 int iLen = 1024; for(int k = 0; k < iLen; k++) { m_lstData.append(QPair<QString, QString>(QString(""), QString(""))); } } int EditModel::rowCount(const QModelIndex &parent) const//返回模型的行数 { return m_lstData.size(); } int EditModel::columnCount(const QModelIndex &parent) const//返回模型的列数 { return 2; } QVariant EditModel::data(const QModelIndex &index, int role) const//及时将model内容的变化修改到qtableview中 { int iRow = index.row(), iCol = index.column(); if(iRow >= 0 && iRow < m_lstData.size() ) { if(Qt::DisplayRole == role) { if(0 == iCol) { return m_lstData.at(iRow).first; } else if(1 == iCol) { return m_lstData.at(iRow).second; } } } return QVariant(); } bool EditModel::setData(const QModelIndex &index, const QVariant &value, int role) //响应手动修改 { if(role == Qt::EditRole) { int iRow = index.row(), iCol = index.column(); if( iRow >= 0 && iRow < m_lstData.size() ) { if(iCol == 0) { m_lstData[iRow].first = value.toString(); } else if(iCol == 1) { m_lstData[iRow].second = value.toString(); } } } return true; } Qt::ItemFlags EditModel::flags(const QModelIndex & index) const //必须有这句,否则无法手动修改模型内容 { return Qt::ItemIsEditable | QAbstractTableModel::flags(index); } void EditModel::vPrint(int iIndex) { qDebug()<<m_lstData.at(iIndex).first; }

     

    #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QHideEvent> #include "EditModel.h" class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); EditModel * m_pModel; protected: void hideEvent(QHideEvent *); }; #endif // MAINWINDOW_H

     

    #include "mainwindow.h" #include <QTableView> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QTableView * pView = new QTableView(this); m_pModel = new EditModel(this);//指定了父之后,父被删除会自动删除EditModel pView->setModel(m_pModel); setCentralWidget(pView); } MainWindow::~MainWindow() { } void MainWindow::hideEvent(QHideEvent *) { m_pModel->vPrint(0); }

    效果:

    为了证明用户在界面写入的内容确实进入了model,这里重写了MainWindow::hideEvent()。当窗口被最小化时,EditModel会打印第0个条目的首元素。从下面的图片可见,表格里输入的rrtg确实打印了出来。

     

    Processed: 0.028, SQL: 8