首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何利用QTreeWidgetItems在QTreeWidget中实现不同高度的QStyledItemDelegate?

如何利用QTreeWidgetItems在QTreeWidget中实现不同高度的QStyledItemDelegate?
EN

Stack Overflow用户
提问于 2020-10-29 22:37:08
回答 1查看 136关注 0票数 1

注意:原来问题并不是因为实现了QStyledItemDelegate**,,而是因为在** MyTreeWidget 的构造函数中,我调用了 setUniformRowHeights(真)。下面的代码和@scopchanov发布的解决方案都是有效的,并且是有效的

QTreeWidget有一个名为itemFromIndex()的受保护方法,我就是这样使其可访问的:

代码语言:javascript
运行
复制
class MyTreeWidget : public QTreeWidget {
    Q_OBJECT
public:
    MyTreeWidget(QWidget *parent) : QTreeWidget(parent) {
        setItemDelegate(new MyItemDelegate(this));
    }

    QTreeWidgetItem treeWidgetItemFromIndex(const QModelIndex& index) {
        return itemFromIndex(index);
    }
}

在我的QStyledItemDelegate中,我存储一个指向MyTreeWidget的指针,然后重写它的虚拟sizeHint()方法,并根据QTreeWidgetItem的类型添加一个填充。

代码语言:javascript
运行
复制
class MyItemDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    MyItemDelegate(QObject *parent) : QStyledItemDelegate(parent) {
        _myTreeWidget = dynamic_cast<MyTreeWidget*>(parent);
    }

    QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const {
        auto treeWidgetItem = _myTreeWidget->treeWidgetItemFromIndex(index);
        QSize padding;
        if (dynamic_cast<MyCustomTreeWidgetItem1*>(treeWidgetItem) {
            padding = {0, 5};
        } else if (dynamic_cast<MyCustomTreeWidgetItem2*>(treeWidgetItem) {
            padding = {0, 10};
        }

        return QStyledItemDelegate::sizeHint(option, index) + padding;
    }
}

这是行不通的,因为委托的sizeHint()并不是每个QTreeWidgetItem都会被调用。

因此,我的文本选项在MyCustomTreeWidgetItem1的构造函数中调用MyCustomTreeWidgetItem1,这似乎也没有任何效果。Qt是否因为有一个委托而忽略它?

另一个选项是设置包含在QWidget中的MyCustomTreeWidgetItem的最小高度,这是通过QTreeWidget::setItemWidget()实现的。

所以,在我使用代表的那一刻,我只被限制在规模之内。我的选择是摆脱委托,还是有其他的办法我可以尝试?

我知道很多人会说从QTreeWidget切换到QTreeView,但目前还不可能。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-30 01:09:03

解决方案

我会以另一种(更简单)的方式来处理这个问题:

  1. 定义不同项目大小的枚举,例如: 枚举ItemType : int { IT_ItemWithRegularPadding,IT_ItemWithBigPadding };
  2. 在创建项时,根据其类型在其用户数据中设置所需的大小,例如: 开关(类型){ case IT_ItemWithRegularPadding: item->setData(0,Qt::UserRole,QSize(0,5));断开;IT_ItemWithBigPadding: item->setData(0,Qt:UserRole,QSize(0,10));中断;}
  3. sizeHint的重新实现中,从索引的数据中检索所需的大小,例如: QSize sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const覆盖{返回QStyledItemDelegate::sizeHint(option )+ index.data(Qt::UserRole).toSize();}

示例

下面是我为您编写的一个示例,演示如何实现建议的解决方案:

代码语言:javascript
运行
复制
#include <QApplication>
#include <QStyledItemDelegate>
#include <QTreeWidget>
#include <QBoxLayout>

class Delegate : public QStyledItemDelegate
{
public:
    explicit Delegate(QObject *parent = nullptr) :
        QStyledItemDelegate(parent){
    }

    QSize sizeHint(const QStyleOptionViewItem &option,
                   const QModelIndex &index) const override {
        return QStyledItemDelegate::sizeHint(option, index)
                + index.data(Qt::UserRole).toSize();
    }
};

class MainWindow : public QWidget
{
public:
    enum ItemType : int {
        IT_ItemWithRegularPadding,
        IT_ItemWithBigPadding
    };

    MainWindow(QWidget *parent = nullptr) :
        QWidget(parent) {
        auto *l = new QVBoxLayout(this);
        auto *treeWidget = new QTreeWidget(this);
        QList<QTreeWidgetItem *> items;

        for (int i = 0; i < 10; ++i)
            items.append(createItem(QString("item: %1").arg(i),
                                    0.5*i == i/2 ? IT_ItemWithRegularPadding
                                                 : IT_ItemWithBigPadding));

        treeWidget->setColumnCount(1);
        treeWidget->setItemDelegate(new Delegate(this));
        treeWidget->insertTopLevelItems(0, items);

        l->addWidget(treeWidget);

        resize(300, 400);
        setWindowTitle(tr("Different Sizes"));
    }

private:
    QTreeWidgetItem *createItem(const QString &text, int type) {
        auto *item = new QTreeWidgetItem(QStringList(text));

        switch (type) {
        case IT_ItemWithRegularPadding:
            item->setData(0, Qt::UserRole, QSize(0, 5));
            break;
        case IT_ItemWithBigPadding:
            item->setData(0, Qt::UserRole, QSize(0, 10));
            break;
        }

        return item;
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

注意:本例根据索引奇数或偶数设置项的大小。可以通过实现您需要区分的项的逻辑来更改这一点。

结果

给定的示例产生以下结果:

偶数项和奇数项的高度不同。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64600160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档