动态控制 QItemDelegate 的大小

controlling size of QItemDelegate dynamically

我有几个关于 QItemDelegates in a QListView 尺寸的问题:

我有一个像这样的 QListView using a QItemDelegate which renders a widget in the delegate's custom paint() 方法:

self.thumbnail = MyCustomWidget()
self.thumbnail.render(painter, QtCore.QPoint(option.rect.x(), option.rect.y()))

但是,这显示 QListView, even though the MyCustomWidget().sizeHint() 中带有 250x260 图像的项目是 250x250,它的 maximumSize() returns 也是 250x250。

我发现罪魁祸首是 QListView's spacing, which I had set to 10. If I set the spacing to 100, I still get the QItemDelegates size of 250x260, but if I just don't use setSpacing() 它以 250x250 的分辨率按预期呈现。 传入 paint 方法的 spacing seems to alter the option.rect,导致大小不正确。 我确实需要 spacing, so I'm a bit confused why the QListView's spacing alters the QItemDelegates 的尺码?这是一个错误吗?

我可以通过直接渲染 QPixmap first, then have the painter draw the QPixmap instead of rendering to the painter 来解决这个问题:

self.thumbnail = MyCustomWidget()
pixmap = QtGui.QPixmap(self.thumbnail.size())
self.thumbnail.render(pixmap)
painter.drawPixmap(option.rect.topLeft(), pixmap)

这会生成我需要的 250x250 图像,但我不明白为什么当我使用 setSpacing 时第一种方法无法呈现正确的尺寸?!

现在,更大的挑战是如何动态缩放 QItemDelegate's via a QSlider 的大小: 我有一个 QSlider in the QListView 应该缩放项目,以便用户可以选择在当前视图中查看更小但更多的项目。我测试了 MyCustomWidget() 的独立实例的大小调整,它工作得很好。

但是,委托不会按预期缩放。这是我的委托代码: class代表(QtGui.QItemDelegate):

def __init__(self, parent = None):

    super(Delegate, self).__init__(parent)
    self.scaleValue = 100 # size in percent (as returned by QSlider)

def paint(self, painter, option, index):
    proxyModel = index.model()
    item = proxyModel.sourceModel().itemFromIndex(proxyModel.mapToSource(index))
    self.thumbnail = ElementThumbnail(item)
    self.thumbnail.scale(self.scaleValue)

    pixmap = QtGui.QPixmap(self.thumbnail.size())
    self.thumbnail.render(pixmap)
    painter.drawPixmap(option.rect.topLeft() * self.scaleValue / 100.0, pixmap)

    super(Delegate, self).paint(painter, option, index)

def setScaleValue(self, value):
    self.scaleValue = value

def sizeHint(self, option, index):
    return ElementThumbnail.thumbSize  * self.scaleValue / 100.0

并且在 QListView 中,我正在使用连接到滑块的 valueChanges 信号的插槽:

def scaleThumbnails(self, value):
    self.itemDelegate().setScaleValue(value)
    self.update()

结果是 QSlider 将裁剪 QItemDelegate 但不会缩放它们,因为 QItemDelegatesizeHint() 仅在首次显示 QListView 时调用。 此外,我需要确保当小部件(最终)缩小时,重新计算 QListView 的布局并且更多项目适合可见区域。

简而言之,我的问题是:

  1. 如何在 QListView 中动态缩放 QItemDelegate
  2. 如何强制 QListView 在代理大小更改后重新计算其布局?

编辑:至于问题 2:QAbstractItemView.doItemsLayout 似乎可以解决问题。虽然仍然想知道问题 1

谢谢, 坦率

原来问题出在我的代码的上下文上,而不是委托。 在将小部件呈现为像素图之前,我正在缩放小部件,这当然使编辑器可以正确缩放,但不是在项目不处于编辑状态时。 所以解决方案是在从小部件渲染后简单地缩放像素图,例如:

scaledPixmap = pixmap.scaled(pixmap.size() * self.scaleValue / 100.0)
painter.drawPixmap(option.rect.topLeft(), scaledPixmap)