我们在使用delegate的时候如下的使用方式已经是耳熟能详了.即:QTableView::setItemDelegate(),QTableView::setItemDelegateForRow(),QTableView::setItemDelegateForColumn()来设置整个tableView使用某个delegate,设置单行使用一个delegate,设置某列使用一个delegate.
但是如果我们要设置某一个单独的cell使用一个特殊的delegate该如何处理呢?话不多说, 我就直接上代码了. 我的环境是:windows10 pro, Qt5.8, vs2015.
testComboBoxDelegate.pro
#-------------------------------------------------
#
# Project created by QtCreator 2018-01-10T14:03:38
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = testComboBoxDelegate
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
mainwindow.cpp \
comboboxdelegate.cpp \
HEADERS += mainwindow.h \
comboboxdelegate.h \
FORMS += mainwindow.ui
comboboxdelegate.h
#ifndef COMBOBOXDELEGATE_H
#define COMBOBOXDELEGATE_H
#include <QStyledItemDelegate>
#include <QVector>
#include <QPair>
class ComboBoxDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
ComboBoxDelegate( QObject * parent=nullptr);
~ComboBoxDelegate();
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
#endif // COMBOBOXDELEGATE_H
comboboxdelegate.cpp
#include "comboboxdelegate.h"
#include <QComboBox>
#include <QtDebug>
#include <QApplication>
#include <QStyle>
#pragma warning(disable:4100)
ComboBoxDelegate::ComboBoxDelegate(QObject *parent)
:QStyledItemDelegate(parent)
{
qDebug()<<"delegate constructor";
}
ComboBoxDelegate::~ComboBoxDelegate()
{
qDebug()<<"delegate destructor";
}
QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QComboBox *editor = new QComboBox(parent);
QHash<QString, QVariant> itemData = index.model()->data(index, Qt::UserRole+2).toHash();
auto iter = itemData.cbegin();
while(iter != itemData.cend() ) {
editor->addItem( iter.key(), iter.value() );
++iter;
}
editor->setCurrentIndex(0);
return editor;
}
void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QComboBox *cb = static_cast<QComboBox*>(editor);
QString value = index.model()->data(index, Qt::DisplayRole).toString();
int data = index.model()->data(index, Qt::UserRole + 1).toInt();
qDebug()<<"text="<<value<<",data="<<data;
int idx = cb->findData(data);
if (idx > -1 ) {
cb->setCurrentIndex(idx);
}
}
void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *cb = static_cast<QComboBox*>(editor);
QString displayData = cb->currentText();
QVariant value = cb->currentData();
model->setData(index, displayData, Qt::DisplayRole);
model->setData( index, value, Qt::UserRole + 1 );
}
void ComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
QT_BEGIN_NAMESPACE
class QStandardItemModel;
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void initModel();
void firstType();
void printModel();
private:
Ui::MainWindow *ui;
QStandardItemModel *_model;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "comboboxdelegate.h"
#include <QStandardItemModel>
#include <QVector>
#include <QPair>
#include <QVariant>
#include <QComboBox>
#include <QMouseEvent>
#include "cbdelegate.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_model(nullptr)
{
ui->setupUi(this);
_model = new QStandardItemModel(this);
ui->tableView->setModel( _model );
connect(ui->pushButtonInit, SIGNAL(clicked()), this, SLOT(initModel()));
connect( ui->pushButtonFirst, SIGNAL(clicked()), this, SLOT(firstType()));
connect(ui->pushButtonPrintModel, SIGNAL(clicked()), this, SLOT(printModel()));
}
MainWindow::~MainWindow()
{
delete _model;
delete ui;
}
void MainWindow::initModel()
{
_model->clear();
_model->setColumnCount( 3 );
QList<QStandardItem *> rowData;
rowData.append( new QStandardItem("first") );
rowData.append( new QStandardItem("breakfirst") );
QStandardItem *cell = new QStandardItem("Potato");
QHash<QString, QVariant> itemData;
itemData.insert("Potato", 1000);
itemData.insert("Tomato", 2000);
itemData.insert("Onion", 3000);
cell->setData(itemData, Qt::UserRole+2);
cell->setData(2000, Qt::UserRole + 1 );
rowData.append( cell);
_model->appendRow(rowData);
rowData.clear();
rowData.append( new QStandardItem("second") );
rowData.append( new QStandardItem("lunch") );
cell = new QStandardItem("SuperMan");
itemData.clear();
itemData.insert("SuperMan", 1);
itemData.insert("SpiderMan", 2);
itemData.insert("SpeedMan", 3);
cell->setData(itemData, Qt::UserRole+2);
cell->setData(2, Qt::UserRole + 1 );
rowData.append( cell);
_model->appendRow(rowData);
rowData.clear();
rowData.append( new QStandardItem("third") );
rowData.append( new QStandardItem("supper") );
cell = new QStandardItem("Iron");
itemData.clear();
itemData.insert("Iron", 1);
itemData.insert("Silicon", 2);
itemData.insert("Stone", 3);
cell->setData(itemData, Qt::UserRole+2);
cell->setData(2, Qt::UserRole + 1 );
rowData.append( cell);
_model->appendRow(rowData);
rowData.clear();
rowData.append( new QStandardItem("Forth") );
rowData.append( new QStandardItem("Vegetable") );
cell = new QStandardItem("Fruit");
itemData.clear();
itemData.insert("strawberry", 1);
itemData.insert("WaterMalon", 2);
itemData.insert("Apple", 3);
cell->setData(itemData, Qt::UserRole+2);
cell->setData(2, Qt::UserRole + 1 );
rowData.append( cell);
_model->appendRow(rowData);
rowData.clear();
rowData.append( new QStandardItem("Fifth") );
rowData.append( new QStandardItem("Meat") );
cell = new QStandardItem("Chicken");
itemData.clear();
itemData.insert("CowMeat", 1);
itemData.insert("Fork", 2);
itemData.insert("Yam", 3);
cell->setData(itemData, Qt::UserRole+2);
cell->setData(2, Qt::UserRole + 1 );
rowData.append( cell);
_model->appendRow(rowData);
rowData.clear();
rowData.append( new QStandardItem("Sixth") );
rowData.append( new QStandardItem("Soup") );
cell = new QStandardItem("Table");
itemData.clear();
itemData.insert("Table", 1);
itemData.insert("Desk", 2);
itemData.insert("Chair", 3);
cell->setData(itemData, Qt::UserRole+2);
cell->setData(2, Qt::UserRole + 1 );
rowData.append( cell);
_model->appendRow(rowData);
rowData.clear();
rowData.append( new QStandardItem("Seventh") );
rowData.append( new QStandardItem("braise") );
cell = new QStandardItem("Instrument");
itemData.clear();
itemData.insert("TV", 1);
itemData.insert("Recorder", 2);
itemData.insert("AirC", 3);
cell->setData(itemData, Qt::UserRole+2);
cell->setData(2, Qt::UserRole + 1 );
rowData.append( cell);
_model->appendRow(rowData);
ui->tableView->resizeColumnsToContents();
ui->tableView->setColumnWidth( 2, 256 );
QAbstractItemDelegate *oldCbd = ui->tableView->itemDelegateForColumn( 2 );
if ( oldCbd != nullptr ) {
delete oldCbd;
}
ComboBoxDelegate *cbd = new ComboBoxDelegate(this);
ui->tableView->setItemDelegateForColumn(2, cbd);
ui->tableView->resizeColumnsToContents();
}
void MainWindow::firstType()
{
QStandardItem *firstTypeItem = _model->item( 3, 2 );
if ( firstTypeItem != nullptr ) {
QHash<QString, QVariant> itemData;
itemData.insert("This is my puppy", 1);
itemData.insert("His name is Buddy", 2);
itemData.insert("He is 2-year-old", 3);
itemData.insert("Smart Boarder Collie", 4);
firstTypeItem->setData(itemData, Qt::UserRole+2);
firstTypeItem->setData(2, Qt::UserRole + 1 );
//下边两行用于直接显式修改后的结果
ui->tableView->openPersistentEditor( firstTypeItem->index() );
ui->tableView->setCurrentIndex( firstTypeItem->index() );
}
ui->tableView->resizeColumnsToContents();
}
void MainWindow::printModel()
{
QItemSelectionModel *selection = ui->tableView->selectionModel();
if ( selection == nullptr ) {
return;
}
if ( selection->hasSelection() == false ) {
return;
}
QString displayTxt = selection->currentIndex().model()->data( selection->currentIndex(), Qt::DisplayRole ).toString();
QString userTxt = selection->currentIndex().model()->data( selection->currentIndex(), Qt::UserRole + 1 ).toString();
ui->plainTextEdit->appendPlainText( QString("displayRole:%1--UserRole1:%2").arg(displayTxt).arg(userTxt) );
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>924</width>
<height>505</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="pushButtonInit">
<property name="text">
<string>Init Model</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButtonPrintModel">
<property name="text">
<string>printModel</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="pushButtonFirst">
<property name="text">
<string>First Type</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>267</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="3">
<widget class="QTableView" name="tableView">
<property name="minimumSize">
<size>
<width>480</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPlainTextEdit" name="plainTextEdit"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>924</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>