动态控制 QItemDelegate 的大小
Posted
技术标签:
【中文标题】动态控制 QItemDelegate 的大小【英文标题】:controlling size of QItemDelegate dynamically 【发布时间】:2016-08-11 03:47:33 【问题描述】:我有几个关于QItemDelegates 在QListView 中的大小的问题:
我有一个使用QItemDelegate 的QListView,它在委托的自定义paint() 方法中呈现一个小部件,如下所示:
self.thumbnail = MyCustomWidget()
self.thumbnail.render(painter, QtCore.QPoint(option.rect.x(), option.rect.y()))
然而,这会在 QListView 中显示具有 250x260 图像的项目,即使 MyCustomWidget().sizeHint() 是 250x250 并且它的 maximumSize() 也返回 250x250。
我发现罪魁祸首是 QListView 的 spacing,我设置为 10。如果我将 spacing 设置为 100,我仍然会得到 QItemDelegates 大小为 250x260,但如果我只是不要使用setSpacing(),它会按预期以250x250 呈现。 spacing 似乎改变了传递给paint方法的option.rect,导致大小不正确。 我确实需要那个spacing,所以我有点困惑为什么QListView 的间距会改变QItemDelegates 的大小?这是一个错误吗?
我可以通过首先渲染QPixmap 来解决这个问题,然后让painter 绘制QPixmap 而不是直接渲染到painter:
self.thumbnail = MyCustomWidget()
pixmap = QtGui.QPixmap(self.thumbnail.size())
self.thumbnail.render(pixmap)
painter.drawPixmap(option.rect.topLeft(), pixmap)
这会产生我需要的 250x250 图像,但我不明白为什么当我使用 setSpacing 时第一种方法无法呈现正确的尺寸?!
现在,更大的挑战是如何通过QSlider 动态缩放QItemDelegate 的大小: 我在QListView 中有一个QSlider,它应该缩放项目,以便用户可以选择在当前视图中查看更小但更多的项目。我测试了 MyCustomWidget() 独立实例的大小调整,它工作得很好。
但是,代表不会按预期进行扩展。这是我的委托代码: 类委托(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 将裁剪QItemDelegates 但不会缩放它们,因为QItemDelegate 的sizeHint() 仅在QListView 首次显示时被调用。 此外,我需要确保当小部件(最终)缩小时,QListView 的布局被重新计算,并且更多的项目适合可见区域。
简而言之,我的问题是:
-
如何在QListView 内动态缩放QItemDelegates?
如何在代理大小更改后强制QListView 重新计算其布局?
编辑:至于问题 2:QAbstractItemView.doItemsLayout 似乎可以解决问题。不过仍然想知道问题 1
谢谢, 坦率的
【问题讨论】:
【参考方案1】:原来问题在于我的代码上下文,而不是委托。 我在将小部件渲染为像素图之前对其进行了缩放,这当然可以使编辑器正确缩放,但在项目未处于编辑状态时则不能。 所以解决方案只是在从小部件渲染后缩放像素图,例如:
scaledPixmap = pixmap.scaled(pixmap.size() * self.scaleValue / 100.0)
painter.drawPixmap(option.rect.topLeft(), scaledPixmap)
【讨论】:
以上是关于动态控制 QItemDelegate 的大小的主要内容,如果未能解决你的问题,请参考以下文章