如何阻止paintEvent绘制子部件?
我想给一个 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()
可以用,但我不知道怎么让这个遮罩变得更平滑。
这就是效果:
2 个回答
0
我找到了一种临时解决办法。你可以通过对子控件使用 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))
不过,这并没有回答我最初的问题。我希望能避免这种情况,而不是简单地遮盖它。所以我不会把这个当作答案。
3
绘制事件会发送给窗口或小部件,告诉它具体哪个区域需要更新,而不是整个小部件的边界区域。当你调用 event.rect()
时,它会返回需要更新的那个矩形区域(据我所知是这样的)。
试着把这一行
painter.drawRoundedRect(event.rect(), 15, 15)
改成这样
painter.drawRoundedRect(self.rect(), 15, 15)
编辑:
你还需要在构造函数的任何地方添加这一行
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
希望这对你有帮助。