PyQt5如何实现QPainter绘制的图形正常显示在QGroupBox内部
问题解决:PyQt5将QPainter绘制内容显示到QGroupBox内部
问题根源
- Qt的绘制规则是每个控件的
paintEvent仅负责绘制自身表面的内容,你在主窗口的paintEvent里绘制的内容天然在QGroupBox的下层,会被子控件遮挡 - 直接修改
paint.begin(self.groupGimble)无效的原因是QGroupBox自带的paintEvent会在你外部绘制完成后触发,自动覆盖你手动绘制的所有内容
解决方案
自定义一个专门用于绘制的QWidget子类,将该子类实例添加到QGroupBox的布局中,所有绘制逻辑都在该自定义绘制类的paintEvent中实现,完美适配你后续多GroupBox分别绘制不同内容的需求。
完整可运行代码
from PyQt5 import QtCore, QtGui, QtWidgets CENTERX = 80 CENTERY = 50 # 原CENTERY为0会导致圆形上半部分被裁切,此处做了适配 RADX = 50 RADY = 50 WIDTH = 160 HEIGHT = 120 # 自定义绘制控件,所有绘制逻辑放在该类内部实现 class DrawCanvas(QtWidgets.QWidget): def paintEvent(self, event): paint = QtGui.QPainter(self) paint.setRenderHint(QtGui.QPainter.Antialiasing) # 填充白色背景 paint.setBrush(QtCore.Qt.white) paint.drawRect(event.rect()) # 绘制黑色圆形 paint.setPen(QtCore.Qt.black) paint.setBrush(QtCore.Qt.black) center = QtCore.QPoint(CENTERX, CENTERY) paint.drawEllipse(center, RADX, RADY) class DrawCircles(QtWidgets.QWidget): def __init__(self, parent=None): super(DrawCircles, self).__init__(parent, QtCore.Qt.WindowStaysOnTopHint) self.setGeometry(300, 300, WIDTH, HEIGHT) # 主布局 self.mainLayout = QtWidgets.QVBoxLayout(self) # 初始化GroupBox self.groupGimble = QtWidgets.QGroupBox("gimble区域") # 给GroupBox设置内部布局 group_layout = QtWidgets.QVBoxLayout(self.groupGimble) # 将自定义绘制控件添加到GroupBox的布局中 self.canvas = DrawCanvas() group_layout.addWidget(self.canvas) # 把GroupBox添加到主布局 self.mainLayout.addWidget(self.groupGimble) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) circles = DrawCircles() circles.show() sys.exit(app.exec_())
关键特性
- 每个QGroupBox可以独立添加不同的自定义绘制Widget,互不干扰
- 绘制区域会自动适配QGroupBox的大小,不需要硬编码坐标做适配
- 如果需要修改绘制内容,仅需要修改对应自定义绘制类的
paintEvent逻辑,调用update()即可触发重绘
内容的提问来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

