model/view模型管理数据和显示层的关系,这种结构分离数据和界面。下面一个例子关于QTableView自定义模型和委托。
ItemDelegate继承QStyledItemDelegate
#include <QStyledItemDelegate> #include <QWidget> #include <QItemDelegate> class ItemDelegate : public QStyledItemDelegate { public: ItemDelegate(); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; }; |
#include "itemdelegate.h" #include <QTimeEdit> #include <QDebug> #include <QTextOption> #include <QPainter> ItemDelegate::ItemDelegate() { } QWidget *ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { qDebug() << index.column(); if(index.column() == 2) { QTimeEdit *lineEdit = new QTimeEdit(parent); lineEdit->setDisplayFormat("mm:ss"); return lineEdit; }else { return QStyledItemDelegate::createEditor(parent, option, index); } } void ItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { if(index.column() == 2) { int secs = index.model()->data(index, Qt::DisplayRole).toInt(); qDebug() << "secs = " << secs; QTimeEdit *timeEdit = qobject_cast<QTimeEdit *>(editor); timeEdit->setTime(QTime(0, secs / 60, secs % 60)); } } void ItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { if (index.column() == 2) { QTimeEdit *timeEdit = qobject_cast<QTimeEdit *>(editor); QTime time = timeEdit->time(); int secs = (time.minute() * 60) + time.second(); model->setData(index, secs); } } void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.column() == 2) { int secs = index.model()->data(index, Qt::DisplayRole).toInt(); QString text = QString("%1:%2").arg(secs / 60, 2, 10, QChar('0')).arg(secs % 60, 2, 10, QChar('0')); QTextOption o(Qt::AlignRight | Qt::AlignVCenter); painter->drawText(option.rect, text, o); } } |
createEditor函数可以编辑修改窗口的小部件,简单来说就是返回自己想要的控件,比如说这个例子是返回的是QTimeEdit控件,可以在tableview表中编辑时间。
自定义model,继承的是QStandardItemModel,当我尝试继承QAbstractTableModel时,发现委托不起作用,原因不明?
#include <QStandardItemModel> class testModel : public QStandardItemModel { public: testModel(); void setHeaderList(QStringList hList); int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; void setStrList(QStringList hList); QVariant headerData(int section, Qt::Orientation orientation, int role) const; private: QStringList strList; QStringList headList; }; |
#include "testmodel.h" #include <QDebug> testModel::testModel() { } void testModel::setHeaderList(QStringList hList) { headList = hList; } int testModel::rowCount(const QModelIndex &parent) const { return strList.count(); } int testModel::columnCount(const QModelIndex &parent) const { return headList.count(); } QVariant testModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) return QVariant(); if(orientation == Qt::Horizontal) return headList.at(section); else return strList.at(section); } void testModel::setStrList(QStringList hList) { strList = hList; } |
model必要的函数要写,其他的根据自己的工程进行添加
tView = new QTableView; tView->setFixedSize(640,280); model = new testModel; model->setColumnCount(3); model->setRowCount(4); QStringList headList; headList << "a" << "b" << "c"; QStringList sList; sList << "1" << "2" << "3" << "4"; QStringList s1List; s1List << "e" << "f" << "g" << "h"; model->setHeaderList(headList); model->setStrList(sList); model->setHorizontalHeaderLabels(headList); for(int i=0; i<4; i++) { QModelIndex index = model->index(i, 0, QModelIndex()); model->setData(index, i); } tView->setModel(model); delegate = new ItemDelegate; tView->setItemDelegateForColumn(2,delegate); |