這是Model/View中的最後一篇了,Qt官方顯然弱化了Controller在MVC中的做用,提供了一個簡化版的Delegate;甚至在Model/View框架的使用中,提供了默認的委託,讓這個控制器越發淡出開發者的實現。git
實際上,Qt Model/View框架中的MVC概念是有誤的,顯而易見的就是Controller的做用,控制器應該只對交互進行控制,渲染方面的工做應該僅由View完成,但Delegate的接口中卻包含了這一塊。不過這都不是這篇文章的重點,咱們只關注Delegate自己。github
這裏咱們也來實現一個自定義Delegate,懷着瞭解Delegate的目的,主要實現如下幾個功能:框架
以不一樣顏色繪製View。
雙擊View方格區域彈出行編輯器,默認覆蓋這個區域,顯示字母。
輸入行編輯器內的內容會被保存,下次點開顯示。
鼠標停留,顯示提示框。
Qt提供了幾個標準的委託:dom
QItemDelegate:Qt**曾經**默認使用的委託。
QStyledItemDelegate。:**如今**默認使用的委託,官方推薦咱們使用這個。(自從Qt 4.4)
爲了熟悉委託藉口,咱們繼承虛基類QAbstractItemDelegate來實現咱們的自定義委託。編輯器
出去虛析構函數,QAbstractItemDelegate總共有9個虛函數,下面分別介紹。函數
paint()
函數用來重繪view。咱們這裏選擇用隨機顏色填充背景:this
void CustomeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!index.isValid() || option.state == QStyle::State_None || !index.isValid()) return; painter->fillRect(option.rect, QColor(m_randomColor(m_generator))); }
createEditor()
和destroyEditor()
的用途很是明顯,雙擊View的時候會彈出一個行編輯器:code
QWidget* CustomeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { return new QLineEdit(parent); } void CustomeDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const { Q_ASSERT(dynamic_cast<QLineEdit*>(editor) != 0); delete dynamic_cast<QLineEdit*>(editor); }
helpEvent()
表示幫助事件,當發生QEvent::ToolTip
或者QEvent::WhatsThis
事件的時候,就會調用這個函數,咱們這裏根據事件不一樣顯示不一樣內容的Tool Tip:blog
bool CustomeDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &index) { if (event->type() == QEvent::ToolTip) { QToolTip::showText(QCursor::pos(), QString("CustomeDelegate Tooltip"), reinterpret_cast<QWidget*>(view), option.rect, 1000); } else if (event->type() == QEvent::WhatsThis) { QToolTip::showText(QCursor::pos(), QString("CustomeDelegate Whatsthis"), reinterpret_cast<QWidget*>(view), option.rect, 1000); } return true; }
當Editor顯示的時候,會調用setEditorData()
這個函數來顯示默認的文字:繼承
void CustomeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { dynamic_cast<QLineEdit*>(editor)->setText(index.data(Qt::DisplayRole).toString()); }
setModelData()
這個函數用來更新Model中的數據:
void CustomeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { model->setData(index, dynamic_cast<QLineEdit*>(editor)->text(), Qt::DisplayRole); }
updateEditorGeometry()
這個函數也會在Editor顯示的時候被調用,雙擊不一樣方格時,咱們用它來更新編輯器的位置和大小:
void CustomeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { dynamic_cast<QLineEdit*>(editor)->setFixedSize(option.rect.width(), option.rect.height()); dynamic_cast<QLineEdit*>(editor)->move(option.rect.topLeft()); }
完整代碼見此處。