Qt mode/view全解五

前四章view都是被动的展示数据,本章介绍如何编辑数据。

其实编辑功能的启用也是mode控制的,mode实现setdata()和flags()就启用了编辑功能。

mymode.h

#include <QAbstractTableModel>
#include <QString>

const int COLS= 3;
const int ROWS= 2;


class MyModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    MyModel(QObject *parent);
    int rowCount(const QModelIndex &parent = QModelIndex()) const override ;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override;
    Qt::ItemFlags flags(const QModelIndex & index) const override ;
private:
    QString m_gridData[ROWS][COLS];  //holds text entered into QTableView
signals:
    void editCompleted(const QString &);
};

定义了一个2行3列的二维数组m_gridData,增加了setData()和flags()函数,并添加一个信号editCompleted(),信号的目的是更新标题栏显示,是非必须的。

mymode.cpp

#include "mymodel.h"


MyModel::MyModel(QObject *parent)
    :QAbstractTableModel(parent)
{
}

//-----------------------------------------------------------------
int MyModel::rowCount(const QModelIndex & /*parent*/) const
{
    return ROWS;
}

//-----------------------------------------------------------------
int MyModel::columnCount(const QModelIndex & /*parent*/) const
{
    return COLS;
}

//-----------------------------------------------------------------
QVariant MyModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole)
    {
        return m_gridData[index.row()][index.column()];
    }
    return QVariant();
}

//-----------------------------------------------------------------
//! [quoting mymodel_e]
bool MyModel::setData(const QModelIndex & index, const QVariant & value, int role)
{
    if (role == Qt::EditRole)
    {
        //save value from editor to member m_gridData
        m_gridData[index.row()][index.column()] = value.toString();
        //for presentation purposes only: build and emit a joined string
        QString result;
        for (int row= 0; row < ROWS; row++)
        {
            for(int col= 0; col < COLS; col++)
            {
                result += m_gridData[row][col] + ' ';
            }
        }
        emit editCompleted( result );
    }
    return true;
}
//! [quoting mymodel_e]

//-----------------------------------------------------------------
//! [quoting mymodel_f]
Qt::ItemFlags MyModel::flags(const QModelIndex &index) const
{
    return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}

setData()的作用就是把参数value的值赋值给相应的数组单元,value就是界面上输入的数据,index指示输入的单元,所以role的角色必然是Qt::EditRole;变量result记录单元格数据,通过信号发出,信号会被主线程接收,显示在标题栏。用户每次编辑单元格,setData()就会被调用,对m_gridData赋值后,就会触发changeData()信号更新界面,当然这是默认行为了(也默认调用了data())。

其实真正允许编辑的标志是flag()函数,setdata()只是进行编辑;Qt的MV模型实际上是MCV模型,即还有C(控制)这一层,我们叫做委托delegate,编辑是通过委托来实现的,在创建编辑器的时候委托要检查是否允许编辑,其实就是检查mode的flags()中设置的Qt::ItemFlags属性,本例启用了Qt::ItemIsEditale就是告诉委托可以编辑数据项,这样setData()就可以工作了。

 

本例为了方便的在标题栏显示编辑的内容,将QTableView放在了Mainwindow上,其实这不是必须的,以下内容可以没有。

mainwindow.h

#include <QtWidgets/QMainWindow>

QT_BEGIN_NAMESPACE // QT_BEGIN_NAMESPACE / QT_END_NAMESPACE are not needed in Qt user code
class QTableView; //forward declaration
QT_END_NAMESPACE


class MainWindow : public QMainWindow
{
    Q_OBJECT
private:
    QTableView *tableView;
public:
    MainWindow(QWidget *parent = 0);
public slots:
    void showWindowTitle(const QString & title);
};

mainwindow.cpp

#include <QTableView>
#include "mainwindow.h"
#include "mymodel.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    tableView = new QTableView(this);
    setCentralWidget(tableView);
    QAbstractTableModel *myModel = new MyModel(this);
    tableView->setModel(myModel);

    //transfer changes to the model to the window title
    connect(myModel, SIGNAL(editCompleted(const QString &)), this, SLOT(setWindowTitle(const QString &)));
}

void MainWindow::showWindowTitle(const QString & title)
{
setWindowTitle(title);
}

运行效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值