【问题标题】:How do I stop paintEvent from painting children widgets?如何停止paintEvent 绘制子小部件?
【发布时间】:2014-05-10 03:21:15
【问题描述】:

我正在尝试为QDialog 添加圆角。我正在定义自己的 paintEvent 方法来创建圆角。它正在工作,但它为所有内容添加了圆形边框。甚至光标也有边框。有什么办法可以禁用这种行为?

示例代码:

from PySide import QtCore, QtGui


class RenameDialog(QtGui.QDialog):
    def __init__(self, parent=None, **kwargs):
        super(RenameDialog, self).__init__(
            parent=parent, f=QtCore.Qt.CustomizeWindowHint)
        self.fieldA = QtGui.QLineEdit(self)
        self.fieldB = QtGui.QLineEdit(self)

        self.setLayout(QtGui.QHBoxLayout())
        self.layout().addWidget(self.fieldA)
        self.layout().addWidget(self.fieldB)

        # Set background transparent.  Only items drawn in paintEvent
        # will be visible.
        palette = QtGui.QPalette()
        palette.setColor(QtGui.QPalette.Base, QtCore.Qt.transparent)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
        self.setPalette(palette)

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        fillColor = QtGui.QColor(75, 75, 75, 255)
        lineColor = QtCore.Qt.gray

        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(QtGui.QPen(QtGui.QBrush(lineColor), 2.0))
        painter.setBrush(QtGui.QBrush(fillColor))
        painter.drawRoundedRect(event.rect(), 15, 15)

我正在尝试使用paintEvent 执行此操作,因为:

  • QDialog 样式表不能使用border-radius。弯曲的边框确实出现了,但角落仍然可见。
  • QDialogs.setMask() 有效,但(据我所知)没有办法对掩码进行抗锯齿处理。

看起来是这样的:

【问题讨论】:

  • 有截图吗? “为所有内容添加圆角边框”听起来很奇怪。
  • 这很奇怪。我添加了一个屏幕截图。在我聚焦该字段之前,第二个字段的边框不会出现。

标签: python qt pyside qdialog paintevent


【解决方案1】:

Paint 事件被发送到带有需要更新的精确矩形的窗口/小部件,而不是小部件的整个边界矩形。当您调用 event.rect() 时,它会返回需要更新的矩形(据我所知)

尝试更改此行 painter.drawRoundedRect(event.rect(), 15, 15) 对此 painter.drawRoundedRect(self.rect(), 15, 15)

编辑: 您还需要在构造函数中的任何位置添加此行 self.setWindowFlags(QtCore.Qt.FramelessWindowHint)

希望这会有所帮助。

【讨论】:

  • 啊!这很有意义。谢谢!哦,我在示例中设置了 CustomizeWindowHint - 这与我的系统 (KDE) 上的 FramelessWindowHint 执行相同的操作。也许它在其他窗口管理器上的行为略有不同。
【解决方案2】:

我现在找到了解决方法。您可以通过在子级上使用 QPainter.eraseRect 并设置正确的样式表来隐藏额外的边框。我还发现使用QPainter.fillRect 在违规区域上绘画也可以。

def paintEvent(self, event):
    painter = QtGui.QPainter(self)
    fillColor = QtGui.QColor(75, 75, 75, 255)
    lineColor = QtCore.Qt.gray

    painter.setRenderHint(QtGui.QPainter.Antialiasing)
    painter.setPen(QtGui.QPen(QtGui.QBrush(lineColor), 2.0))
    painter.setBrush(QtGui.QBrush(fillColor))
    painter.drawRoundedRect(event.rect(), 15, 15)

    # Sketchy fix:
    painter.eraseRect(self.childrenRect())
    # OR
    painter.fillRect(self.childrenRect(), QtGui.QBrush(fillColor))

但这并没有回答我原来的问题。我想避免这种行为而不是掩盖它。所以我不会将此标记为答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 2022-10-17
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    相关资源
    最近更新 更多