QTableview 委托例子

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QTableview 委托例子相关的知识,希望对你有一定的参考价值。

参考技术A 委托类和变量

DateDelegate m_dateDelegate;

    ComboDelegate m_comboDelegate;

    SpinDelegate m_spinDelegate;

    CheckBoxDelegate m_CheckBoxDelegate;

//ttableview添加委托

m_modle = new QStandardItemModel(this);

    setModel(m_modle);

    m_modle->setColumnCount(6);

    m_modle->setHeaderData(0,Qt::Horizontal,"Name");//

    m_modle->setHeaderData(1,Qt::Horizontal,"Birthday");

    m_modle->setHeaderData(2,Qt::Horizontal,"Job");

    m_modle->setHeaderData(3,Qt::Horizontal,"Income");

    m_modle->setHeaderData(4,Qt::Horizontal,"yes1");

    m_modle->setHeaderData(5,Qt::Horizontal,"yes2");

    this->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    setItemDelegateForColumn(1, &m_dateDelegate);

    setItemDelegateForColumn(2, &m_comboDelegate);

    setItemDelegateForColumn(3, &m_spinDelegate);

    setItemDelegateForColumn(4, &m_CheckBoxDelegate);//双击或选中才能显示,不使用

    m_modle->setItem(0,0, new QStandardItem("Tom"));

    m_modle->setItem(0,1, new QStandardItem("1977-01-05"));

    m_modle->setItem(0,2, new QStandardItem("工人"));

    m_modle->setItem(0,3, new QStandardItem("1500"));

    //m_modle->indexFromItem()

    setIndexWidget(m_modle->index(0, 5), new QCheckBox(this));

//类原形

#ifndef DATEDELEGATE_H

#define DATEDELEGATE_H

#include

#include

class DateDelegate : public QItemDelegate



  Q_OBJECT

public:

    DateDelegate(QObject *parent = 0) :  QItemDelegate(parent)

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const

   

        QDateTimeEdit *editor = new QDateTimeEdit(parent);

        editor->setDisplayFormat("yyyy-MM-dd");

        editor->setCalendarPopup(true);

        editor->installEventFilter(const_cast(this));

        return editor;

   

    void setEditorData(QWidget *editor, const QModelIndex &index) const

   

        QString dateStr= index.model()->data(index).toString();

        QDate date = QDate::fromString(dateStr,Qt::ISODate);

        QDateTimeEdit *edit=static_cast(editor);

        edit->setDate(date);

   

    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const

   

        QDateTimeEdit *edit=static_cast(editor);

        QDate date = edit->date();

        model->setData(index,QVariant(date.toString(Qt::ISODate)));

   

    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const

   

        editor->setGeometry(option.rect);

   

;

#endif // DATEDELEGATE_H

#ifndef COMBODELEGATE_H

#define COMBODELEGATE_H

#include <QComboBox>

#include <QItemDelegate>

class  ComboDelegate :  public  QItemDelegate



    Q_OBJECT

public :

    ComboDelegate(QObject *parent = 0): QItemDelegate(parent)

    QWidget *createEditor(QWidget *parent,  const QStyleOptionViewItem &option,

        const  QModelIndex &index)  const

   

        QStringList list;

        list << "工人" << "农民" << "军人" << "律师";

        QComboBox *editor = new QComboBox(parent);

        editor->addItems(list);

        editor->installEventFilter(const_cast(this));

        return editor;

   

    void  setEditorData(QWidget *editor,  const  QModelIndex &index)  const

   

        QString dateStr = index.model()->data(index).toString();

        QComboBox *box = static_cast(editor);

        int i = box->findText(dateStr);

        box->setCurrentIndex(i);

   

    void  setModelData(QWidget *editor, QAbstractItemModel *model,

        const  QModelIndex &index)  const

   

        QComboBox *box = static_cast(editor);

        QString str = box->currentText();

        model->setData(index,str);

   

    void  updateEditorGeometry(QWidget *editor,

        const  QStyleOptionViewItem &option,  const  QModelIndex &index) const

   

        editor->setGeometry(option.rect);

   

;

#endif // COMBODELEGATE_H

#ifndef SPINDELEGATE_H

#define SPINDELEGATE_H

#include

#include

class SpinDelegate : public QItemDelegate



    Q_OBJECT

public:

    SpinDelegate(QObject *parent = 0) : QItemDelegate(parent)

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const

   

        QSpinBox *editor = new QSpinBox(parent);

        editor->setRange(0,10000);

        editor->installEventFilter(const_cast(this));

        return editor;

   

    void setEditorData(QWidget *editor, const QModelIndex &index) const

   

        int value =index.model()->data(index).toInt();

        QSpinBox *box = static_cast(editor);

        box->setValue(value);

   

    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const

   

        QSpinBox *box = static_cast(editor);

      int value = box->value();

      model->setData(index,value);

   

    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const

   

        editor->setGeometry(option.rect);

   

;

#endif // SPINDELEGATE_H

#ifndef CHECKBOXDELEGATE_H

#define CHECKBOXDELEGATE_H

#include

#include

class CheckBoxDelegate : public QItemDelegate



    Q_OBJECT

public:

    CheckBoxDelegate(QObject *parent = 0) : QItemDelegate(parent)

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const

   

        QCheckBox *editor = new QCheckBox(parent);

        editor->installEventFilter(const_cast(this));

        return editor;//双击或选中才能显示

   

    void setEditorData(QWidget *editor, const QModelIndex &index) const

   

        bool value =index.model()->data(index).toBool();

        QCheckBox *box = static_cast(editor);

        box->setChecked(value);

   

    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const

   

      QCheckBox *box = static_cast(editor);

      bool value = box->isChecked();

      model->setData(index,value);

   

    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const

   

        editor->setGeometry(option.rect);

   

;

#endif // CHECKBOXDELEGATE_H

如何为 QTableView 中的单个单元格设置委托?

【中文标题】如何为 QTableView 中的单个单元格设置委托?【英文标题】:how to set a delegate for a single cell in QTableView? 【发布时间】:2021-07-14 00:58:39 【问题描述】:

QTableView 类为 setDelegate 提供了 3 个接口:

setItemDelegate -- 为整个 QTableView 设置委托

setItemDelegateForRow -- 为给定行设置委托

setItemDelegateForColumn -- 为给定列设置委托

问题:如果我只想为一个单元格设置委托,我该怎么做?

例如,我有一个包含两列的 Qtableview,第一列设置有自定义 QCombobox 委托,其中包含人类和植物项目。第二列也设置了QCombobox委托,但可选项目取决于第一列的选择。这意味着第二列中的每个单元格可能有不同的代表。

例如,如果 data(row=1, col=1) 从组合框委托中选择为人类,则 cell(row=1, col=2) 有一个组合框委托,其中包含项目 header、body、hand、foot ;如果从组合框委托中选择 data(row=2, col=1) 作为植物,则 cell(row=2, col=2) 具有包含根、叶、花项的组合框委托。

有类似的问题,但还没有回答,Set Delegate for each cell in a QTableView?

【问题讨论】:

【参考方案1】:

我想你有一个XY problem。该逻辑与每个单元格的委托无关,而是实现基于 QModelIndex(提供行和列)的逻辑。

import random
import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import (
    QApplication,
    QComboBox,
    QStyledItemDelegate,
    QTableView,
    QWidget,
)

OPTIONS = 
    "human": ["header", "body", "hand", "foot"],
    "plant": ["root", "leaf", "flower"],



class Delegate(QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        editor = QComboBox(parent)
        editor.currentTextChanged.connect(self.handle_commit_close_editor)
        return editor

    def setEditorData(self, editor, index):
        if index.column() == 0:
            option = index.data()
            editor.clear()
            editor.addItems(list(OPTIONS.keys()))
            editor.setCurrentText(option)

        elif index.column() == 1:
            option = index.sibling(index.row(), 0).data()
            options = OPTIONS.get(option, [])
            editor.clear()
            editor.addItems(options)

    def setModelData(self, editor, model, index):
        if index.column() == 0:
            option = editor.currentText()
            model.setData(index, option, Qt.DisplayRole)
            options = OPTIONS.get(option, [])
            model.setData(
                index.sibling(index.row(), 1),
                options[0] if options else "",
                Qt.DisplayRole,
            )
        elif index.column() == 1:
            option = editor.currentText()
            model.setData(index, option, Qt.DisplayRole)

    def handle_commit_close_editor(self):
        editor = self.sender()
        if isinstance(editor, QWidget):
            self.commitData.emit(editor)
            self.closeEditor.emit(editor)


def main():
    app = QApplication(sys.argv)

    app.setStyle("fusion")

    model = QStandardItemModel(0, 2)

    for i in range(4):
        option = random.choice(list(OPTIONS.keys()))
        item_1 = QStandardItem(option)
        item_2 = QStandardItem(random.choice(list(OPTIONS[option])))
        model.appendRow([item_1, item_2])

    view = QTableView()
    view.setModel(model)
    view.resize(640, 480)
    view.show()

    delegate = Delegate(view)
    view.setItemDelegate(delegate)

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

【讨论】:

非常感谢,它对我有用。我尝试了另一种方法,但它不如这个。【参考方案2】:

对此没有直接的解决方案,至少(据我所知)来自 PyQt5。

问题是所有项目视图类都使用一个私有(并且无法从 PyQt 访问)delegateForIndex 函数,该函数首先检查行并返回该行的委托(如果存在),然后对列执行相同操作(同样,如果存在的话)并最终返回默认委托(内置委托或具有通用 setItemDelegate() 的集合)。

因此,如果您想确保代理首先始终基于行/列对(然后“回退”到某些行或列相关行为),唯一的解决方案就是使用一个unique委托,然后根据行/列位置实现相关功能。

【讨论】:

以上是关于QTableview 委托例子的主要内容,如果未能解决你的问题,请参考以下文章

将自定义委托与从 QTableView 派生的类一起使用

当委托失去焦点时取消 QTableView 中的编辑

QTableView 上的 PySide 委托,带有文本和刻度

在 QTableView 中设置 QPlainTextEdit 委托的高度

QT QTableView 使用委托

在 qtableview pyqt4 python 中使用图像委托?