[英]why When I large the size of Windows, the pen does not painting at the coordinate point of the mouse in pyqt5
[英]PyQt5: Why does the default style of a QGroupBox disappear when painting?
我的应用程序使用排列在 QGridLayout 中的各种 QGroupBox 来显示信息。 我希望其中一个显示我绘制的自定义形状。 由于我希望形状是 GroupBox 并且很难获得小部件相对于窗口的位置,因此我决定将 GroupBox 子类化并将绘制事件添加到子类中。 这很好用,但是它完全消除了 GroupBox 的默认样式,包括标题。
下面的代码创建了一个带有两个 GroupBox 的简单窗口,一个使用标准类,一个使用子类中的绘制事件。 您应该看到右边的只有绘制的矩形,没有 GroupBox 样式。
如果您注释掉绘制事件,则 GroupBox 将照常显示。 为什么会发生这种情况,我应该怎么做才能保持 GroupBox 风格? 是否有另一种方法可以在不使用子类中的绘制事件的 GroupBox 中使用画家?
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class MainWindow(QWidget):
def __init__(self, *args, **kwargs):
## Set up Window layout
super(MainWindow, self).__init__(*args, **kwargs)
self.layout = QGridLayout()
self.setLayout(self.layout)
self.setGeometry(300, 50, 1000, 700)
leftGroup = QGroupBox('Left Group')
self.layout.addWidget(leftGroup, 0, 0)
rightGroup = RightGroup()
self.layout.addWidget(rightGroup, 0, 1)
class RightGroup(QGroupBox):
def __init__(self):
super(RightGroup, self).__init__('Right Group')
def paintEvent(self, event):
painter = QPainter(self)
# Paint Style
painter.setPen(QPen(Qt.black, .5, Qt.SolidLine))
painter.drawRect(QRectF(0, 0, self.width(), self.height()))
if __name__ == '__main__':
## Creates a QT Application
app = QApplication([])
## Creates a window
window = MainWindow()
## Shows the window
window.show()
app.exec_()
您正在覆盖整个绘画,“覆盖”意味着您忽略默认行为。
标准 Qt 小部件的paintEvent()
的默认行为导致绘制该小部件(无论是按钮、标签、组框等)。 如果您只是覆盖它,则该小部件将永远不会被绘制,除非您调用默认实现(即: super().paintEvent(event)
)。
例如,考虑以下情况:
class RightGroup(QGroupBox):
pass
这将正确显示一个正常的组框。
现在,这个:
class RightGroup(QGroupBox):
def paintEvent(self, event):
pass
不会显示任何内容,因为您明确忽略了默认绘画行为。 要“恢复”它并添加自定义绘图:
class RightGroup(QGroupBox):
def paintEvent(self, event):
super().paintEvent(event)
qp = QPainter(self)
qp.drawRect(self.rect().adjusted(0, 0, -1, -1)
注意:除非您使用抗锯齿且笔宽小于或等于 0.5,否则应始终将对象矩形的右/下边缘限制为小于或等于笔宽一半的整数。 这就是上面adjusted(0, 0, -1, -1)
的原因。 对于您上面的代码,它将是QRectF(0, 0, self.width() - 1, self.height() - 1)
也就是说,您可能希望在该组框内绘图,因此,更好的解决方案是为该组框的内容创建一个子类,将其添加到该组框并覆盖该子类的绘制事件。
class MainWindow(QWidget):
def __init__(self, *args, **kwargs):
# ...
rightGroup = QGroupBox('Right Group')
self.layout.addWidget(rightGroup, 0, 1)
rightLayout = QVBoxLayout(rightGroup)
rightLayout.addWidget(Canvas())
class Canvas(QWidget):
def __init__(self):
super().__init__()
self.path = QPainterPath()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.path.moveTo(event.pos())
def mouseMoveEvent(self, event):
# note: here we use "buttons", not "button".
if event.buttons() == Qt.LeftButton:
self.path.lineTo(event.pos())
self.update()
def mouseReleaseEvent(self, event):
self.update()
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHints(painter.Antialiasing)
painter.setPen(QPen(Qt.black, .5, Qt.SolidLine))
painter.drawRect(self.rect())
painter.drawPath(self.path)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.