【问题标题】:How to use Qt Delegates for custom painting?如何使用 Qt Delegates 进行自定义绘画?
【发布时间】:2011-01-21 01:16:33
【问题描述】:

当一个项目被拖到 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()

【问题讨论】:

  • 接管(文本等)的渲染可能比试图弄清楚如何覆盖标准渲染的部分花费更少的精力。

标签: python qt pyqt


【解决方案1】:

这很容易通过使用 c++ 的 qt 解决:您可以定义一个新样式,覆盖 drawPrimitive 方法并在那里进行自定义绘制(或什么都不做),只要通过 element 接收到 QStyle::PE_IndicatorItemViewItemDrop 常量em> 参数。下面是一个例子:

class TestStyle : public QProxyStyle
{
public:
    TestStyle(QStyle *baseStyle = 0) : QProxyStyle(baseStyle) {}

    void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
    {
        if (element == QStyle::PE_IndicatorItemViewItemDrop)
        {
            //?? do nothing or do custom painting here
        }
        else
        {
            QProxyStyle::drawPrimitive(element, option, painter, widget);
        }
    }
};

.. 

ui->treeView->setStyle(new TestStyle(ui->treeView->style()));

现在坏消息是 pyqt 似乎对 QProxyStyle 一无所知;看起来它没有包装在那里,所以为了让它工作,你需要自己包装样式类。

另一种解决方案是创建自定义 QTreeView 后代并覆盖其paintEvent 方法。默认实现是调用drawTree 和paintDropIndicator;其中paintDropIndicator 负责拖放指示器,而drawTree 渲染树项。 drawTree 受到保护,您可以从您的paintEvent 中调用:

class TestTreeView : public QTreeView
{
public:
    explicit TestTreeView(QWidget *parent = 0) : QTreeView(parent) {}

    void paintEvent(QPaintEvent * event)
    {
        QPainter painter(viewport());
        drawTree(&painter, event->region());
    }
};

这应该抑制默认的拖放指示器。如果您在将其转换为 python 时遇到问题,请告诉我。

希望这会有所帮助,问候

【讨论】:

  • 第二种方法很有效,而且很简单。谢谢!!
猜你喜欢
  • 2023-01-25
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
  • 2021-12-25
  • 2014-08-17
  • 2023-03-11
  • 2014-06-25
  • 2011-04-13
相关资源
最近更新 更多