Qt tableview 使用ComboBox作为delegate时,实现单个cell中的comboBox的item动态变化以及独特性

我们在使用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>





  • 5
    点赞
  • 18
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

donwmufromdying

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值