注意:原来问题并不是因为实现了QStyledItemDelegate
**,,而是因为在** MyTreeWidget
的构造函数中,我调用了 setUniformRowHeights(真)。下面的代码和@scopchanov发布的解决方案都是有效的,并且是有效的。
QTreeWidget
有一个名为itemFromIndex()
的受保护方法,我就是这样使其可访问的:
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
的类型添加一个填充。
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
,但目前还不可能。
发布于 2020-10-30 01:09:03
解决方案
我会以另一种(更简单)的方式来处理这个问题:
sizeHint
的重新实现中,从索引的数据中检索所需的大小,例如:
QSize sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const覆盖{返回QStyledItemDelegate::sizeHint(option )+ index.data(Qt::UserRole).toSize();}示例
下面是我为您编写的一个示例,演示如何实现建议的解决方案:
#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();
}
注意:本例根据索引奇数或偶数设置项的大小。可以通过实现您需要区分的项的逻辑来更改这一点。
结果
给定的示例产生以下结果:
偶数项和奇数项的高度不同。
https://stackoverflow.com/questions/64600160
复制相似问题