如何使用Qt Delegates进行自定义绘画?
我试图覆盖当项目被拖动到 QTreeWidgetItems 上时绘制 QTreeWidgetItems 的方式。我已经重写了拖动事件,将我想要绘制的 QTreeWidgetItems 的 Qt.UserRole 数据设置为 1。在 Item Delegate 中,我读取 UserRole 并进行相应的绘制。
我的自定义绘画完全按照预期显示(即粗体线);但是,我无法弄清楚如何在不抑制所有其他绘画(即文本等)的情况下抑制标准画家进行拖动(即小矩形)所做的绘图。
任何想法将不胜感激。
例如。
def dragMoveEvent(self, event):
pos = event.pos()
item = self.myTreeWidget.itemAt(pos)
# If hovered over an item during drag, set UserRole = 1
if item:
index = self.myTreeWidget.indexFromItem(item)
self.myTreeWidget.model().setData(index, 1, Qt.UserRole)
# reset UserRole to 0 for all other indices
for i in range(self.myTreeWidget.model().rowCount()):
_index = self.myTreeWidget.model().index(i, 0)
if not item or index != _index:
self.myTreeWidget.model().setData(_index, 0, Qt.UserRole)
class MyDelegate(QStyledItemDelegate):
def paint( self, painter, option, index ):
QStyledItemDelegate.paint(self, painter, option, index)
painter.save()
data = index.model().data( index, Qt.UserRole ).toInt()
# if UserRole = 1 draw custom line
if data[1] and data[0] == 1:
line = QLine( option.rect.topLeft(), option.rect.topRight() )
painter.drawLine( line )
painter.restore()
I'm trying to override the way QTreeWidgetItems are drawn when an item is dragged over them. I've overridden the drag Events to set the Qt.UserRole data to 1 for the QTreeWidgetItems that I want to paint. In the Item Delegate, I read the UserRole and draw accordingly.
My custom painting is showing up exactly as expected (i.e. the bolded line); however, I have not been able to figure out how to suppress the drawing done by the standard painter for Dragging (i.e. the small rectangle) without suppressing all other painting (i.e. the text, etc.).
Any ideas would be appreciated.
Ex.
def dragMoveEvent(self, event):
pos = event.pos()
item = self.myTreeWidget.itemAt(pos)
# If hovered over an item during drag, set UserRole = 1
if item:
index = self.myTreeWidget.indexFromItem(item)
self.myTreeWidget.model().setData(index, 1, Qt.UserRole)
# reset UserRole to 0 for all other indices
for i in range(self.myTreeWidget.model().rowCount()):
_index = self.myTreeWidget.model().index(i, 0)
if not item or index != _index:
self.myTreeWidget.model().setData(_index, 0, Qt.UserRole)
class MyDelegate(QStyledItemDelegate):
def paint( self, painter, option, index ):
QStyledItemDelegate.paint(self, painter, option, index)
painter.save()
data = index.model().data( index, Qt.UserRole ).toInt()
# if UserRole = 1 draw custom line
if data[1] and data[0] == 1:
line = QLine( option.rect.topLeft(), option.rect.topRight() )
painter.drawLine( line )
painter.restore()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用 c++ 使用 qt 可以轻松解决此问题:您可以定义新样式,覆盖 drawPrimitive< /a> 方法,并在通过 element 参数接收 QStyle::PE_IndicatorItemViewItemDrop 常量时进行自定义绘制(或什么都不做)。下面是一个例子:
现在坏消息是 pyqt 似乎对 QProxyStyle 一无所知;看起来它没有包装在那里,所以为了让它工作,你需要自己包装样式类。
另一个解决方案是创建自定义 QTreeView 后代并覆盖其 paintEvent方法。默认实现是调用 drawTree 和paintDropIndicator;其中paintDropIndicator 负责拖放指示器,drawTree 渲染树项。 drawTree 受到保护,可供您从 PaintEvent 中调用:
这应该会抑制默认的拖放指示器。如果您在将其转换为 python 时遇到问题,请告诉我。
希望这有帮助,问候
this is easily solvable with qt using c++: you can define a new style, override drawPrimitive method and do custom painting (or just do nothing) there whenever QStyle::PE_IndicatorItemViewItemDrop constant is received via element parameter. Below is an example:
now the bad news is that pyqt doesn't seem to know anything about QProxyStyle; looks like it's not wrapped there, so in order for this to work you would need to wrap style classes yourself.
another solution is to create a custom QTreeView descendant and override its paintEvent method. Default implementation is calling drawTree and paintDropIndicator; where paintDropIndicator is responsible for drag and drop indicator, and drawTree renders tree items. drawTree is protected and available for you to call from your paintEvent:
this should suppress the default drag and drop indicator. Let me know if you're having troubles converting it to python.
hope this helps, regards