正确实现 QStyledItemDelegate

Posted

技术标签:

【中文标题】正确实现 QStyledItemDelegate【英文标题】:Correctly implementing QStyledItemDelegate 【发布时间】:2013-07-29 23:56:29 【问题描述】:

我有一个包含 QTreeWidget 的类 (EditorTagManager)。在运行时,树可以包含任意数量的标签项,所有这些都是可检查的。我试图在 QTreeWidgetItems 之间添加水平线,以明确这些标签是不相关的并且是相互分开的(每个项目都是一个根级节点)。

从我对该主题的研究中,我发现在任何有意义的程度上控制 QtreeWidgetItems 的外观的唯一方法是继承 QStyledItemDelegate 并将委托绑定到 QTreeWidget。这是一个抽象的概念,所以我不完全理解它。因为我以前从未需要对 Qt 对象进行子类化,所以我不确定我是否正确地进行了操作。

由于 Qt 文档没有真正解释如何执行此操作,因此我使用 Clementine 1.0.1 源代码中的 settingsdialog.cpp/.h 文件作为我的指南/参考,因为 Clementine 的首选项窗口在其 QTreeWidget 上使用了类似的分隔符.我正在尝试从 Clementine 的代码对我自己的解决方案进行逆向工程,唯一的问题是 Clementine 的实现做了我不需要的事情(所以我必须弄清楚什么与我的代码相关,什么不相关)。这就是让我走到这一步的原因;我的代码与 Clementine 代码非常相似(我只是更改了委托类名称):

这是我当前在 editortreemanager.h 中的委托头声明:

class TagListDelegate : public QWidget


public:
    TagListDelegate(QObject* parent);
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
                const QModelIndex& index) const;
;

这是我当前在 editortreemanager.cpp 中的委托源:

TagListDelegate::TagListDelegate(QObject *parent) :
    TagListDelegate(parent)



void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                            const QModelIndex &index) const


尽管 TagListDelegate::paint() 实际上还没有做任何事情,但我只是想让这段代码正常工作,然后再尝试更改 QTreeWidgetItems 的外观。我的目标是现在尽可能简单。

在我告诉 QTreeWidget (ui->AvailableTags) 使用委托之前,一切都编译得很好:

ui->AvailableTags->setItemDelegate(new TagListDelegate(this)); 

编译器错误如下:

/home/will/qt_projects/robojournal/ui/editortagmanager.cpp:211:错误: 没有匹配的调用函数 'QTreeWidget::setItemDelegate(TagListDelegate*)'

我在这里有点不知所措,所以我肯定会感谢一些帮助来解决这个问题。

更新(2013 年 7 月 30 日):

我的 Delegate 类现在看起来像这样:

来源:

TagListDelegate::TagListDelegate(QStyledItemDelegate *parent) :
    TagListDelegate(parent)



void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                            const QModelIndex &index) const

    QStyledItemDelegate::paint(painter, option, index);


标头声明:

class TagListDelegate : public QStyledItemDelegate


public:
    TagListDelegate(QStyledItemDelegate* parent);
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
                const QModelIndex& index) const;
;

更新(2013 年 7 月 31 日)

这是我的课程现在的样子:

标题:

class TagListDelegate : public QStyledItemDelegate


public:
    TagListDelegate(QObject* parent);
    QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
    void paint(QPainter* painter, const QStyleOptionViewItem& option,
                const QModelIndex& index) const;
;

来源:

TagListDelegate::TagListDelegate(QObject *parent)
    : TagListDelegate(parent)



QSize TagListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const

     QSize ret = QStyledItemDelegate::sizeHint(option, index);
     return ret;



void TagListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                            const QModelIndex &index) const

    QStyledItemDelegate::paint(painter, option, index);


【问题讨论】:

【参考方案1】:

您没有在代码中继承 QStyledItemDelegate。您正在继承 QWidget。 改变

class TagListDelegate : public QWidget

到:

class TagListDelegate : public QStyledItemDelegate

并且不要忘记包含标题:

#include <QStyledItemDelegate>

【讨论】:

好的,我已经完成了,但是通过运行 ui->AvailableTags->setItemDelegate(new TagListDelegate(this)); 调用委托还是不行。 @WillKraft 在您的构造函数中,您要求 QStyledItemDelegate 类型的对象作为父对象,而您应该要求 QWidgetQObject 类型。 Thuga:你的最新建议有点帮助;当我调用委托时,代码现在可以编译,但每当实例化委托时,应用程序就会出现段错误。调试器说它与构造函数有关,特别是父(this)不可用。我的最新代码(见上文)基本上是 Clementine 委托代码的精简版,所以我不确定问题出在哪里。 其实我可能刚刚修好了。现在我已经将构造函数设置为 TagListDelegate::TagListDelegate(QObject *parent) : QStyledItemDelegate(parent) 它不会崩溃 是的,现在肯定已经修复了。感谢您的帮助。

以上是关于正确实现 QStyledItemDelegate的主要内容,如果未能解决你的问题,请参考以下文章

如何正确检查对象是不是实现接口

如何正确实现接口?

实现 C# 控制台应用程序的正确方法?

这个访问者实现是不是正确?

实现 QThread 的正确方法是啥...(请举例...)

ios实现like按钮的正确方法