To draw directly onto a widget you can override it's paintEvent
. The thing to remember when doing so is that paintEvent
fires every time the Widget deems it necessary to redraw itself e.g. when it has been resized or moved. This means that when implementing your own version of paintEvent
you need to draw all the shapes you want drawn on your widget. Note that paintEvent
is rarely called directly. If you want the widget to redraw itself, you should call update()
which will schedule a paintEvent
for you.
这是一个简单的示例,其中在单击按钮时将任意矩形添加到画布。矩形存储在Canvas
对象的数组中。在中Canvas.paintEvent
,我们创建的实例,QPainter
并使用此对象绘制数组中的所有矩形。
from PyQt5 import QtWidgets, QtGui, QtCore
from random import randrange
class Canvas(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.rectangles = []
def add_rectangle(self, rect, color):
self.rectangles.append((rect, color))
self.update()
def paintEvent(self, event):
painter = QtGui.QPainter(self)
brush = QtGui.QBrush(QtCore.Qt.white)
painter.setBrush(brush)
painter.drawRect(event.rect())
pen = QtGui.QPen()
pen.setWidth(3)
for rect, color in self.rectangles:
pen.setColor(color)
painter.setPen(pen)
brush.setColor(color)
painter.setBrush(brush)
painter.drawRect(rect)
class MyWindow(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.canvas = Canvas(self)
self.button = QtWidgets.QPushButton('Add rectangle')
self.button.clicked.connect(self.add_rectangle)
self.layout = QtWidgets.QVBoxLayout(self)
self.layout.addWidget(self.canvas)
self.layout.addWidget(self.button)
self.resize(500,500)
def add_rectangle(self):
w = self.canvas.width()
h = self.canvas.height()
x0, y0 = randrange(w), randrange(h)
x1, y1 = randrange(w), randrange(h)
shape = QtCore.QRect(min(x0,x1), min(y0,y1), abs(x0-x1), abs(y0-y1))
color = QtGui.QColor.fromRgb(*(randrange(256) for i in range(3)), 180)
self.canvas.add_rectangle(shape, color)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
window = MyWindow()
window.show()
app.exec()
非常感谢您的支持!稍后,我将尝试在仿真中实现它,但它看起来与我一直在寻找的东西完全一样!
它的工作原理是必须使用self.repaint()而不是self.update()