PyQt5技术问询:无需新增类在次级窗口绘椭圆及布局嵌图形
解决你的PyQt5绘图问题
嘿,我来帮你搞定这两个问题~
问题1:点击按钮后在QDialog中绘制椭圆(无需新类)
你之前的代码里,主窗口的paintEvent只负责绘制主窗口的内容,而弹出的QDialog本身没有重写paintEvent,所以自然不会显示椭圆。不用新建类的话,我们可以直接给QDialog实例动态绑定paintEvent方法,具体修改如下:
在你的SecondWin方法里,给创建的mydialog添加自定义的绘制逻辑:
def SecondWin(self): mydialog = QDialog(self) mydialog.setWindowTitle("Second Window") mydialog.setGeometry(400,200,600,300) # 给QDialog动态定义paintEvent def dialog_paint_event(event): painter = QPainter(mydialog) painter.setPen(QPen(QtCore.Qt.red,6,QtCore.Qt.SolidLine)) painter.setBrush(QBrush(QtGui.QColor(45,171,200),QtCore.Qt.SolidPattern)) # 调整椭圆位置和大小,适配QDialog的尺寸 painter.drawEllipse(150, 50, 300, 200) mydialog.paintEvent = dialog_paint_event mydialog.show()
这样点击按钮后,弹出的QDialog就会自动调用我们定义的绘制方法,显示椭圆啦~
问题2:能否将几何图形插入Box Layout?
答案是不能直接插入,因为Qt的Layout管理器只能管理QWidget及其子类对象,而几何图形(比如用QPainter画的椭圆)不是控件。不过我们可以用间接的方法实现:
- 自定义QWidget承载绘图:创建一个QWidget子类,在它的
paintEvent里绘制几何图形,然后把这个自定义Widget添加到Box Layout中。 - 用QLabel显示绘图:先在QPixmap上绘制图形,然后把QPixmap设置给QLabel,再将QLabel加入Layout。
举个简单的例子,用自定义Widget的方式:
# 假设我们在主窗口里添加一个Box Layout def Create_Button(self): button = QPushButton("Click", self) button.setGeometry(30,100,200,80) button.clicked.connect(self.SecondWin) # 新增:创建一个水平布局和承载绘图的Widget from PyQt5.QtWidgets import QHBoxLayout, QWidget layout = QHBoxLayout() central_widget = QWidget() self.setCentralWidget(central_widget) central_widget.setLayout(layout) # 自定义绘图Widget draw_widget = QWidget() draw_widget.setFixedSize(300, 300) # 给widget绑定paintEvent def widget_paint(event): painter = QPainter(draw_widget) painter.setPen(QPen(QtCore.Qt.blue, 4)) painter.drawRect(50,50,200,200) draw_widget.paintEvent = widget_paint layout.addWidget(draw_widget) layout.addWidget(button)
这样就能把带有几何图形的Widget放进Layout里管理了。
修改后的完整代码
#!/usr/bin/python3.6 # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QDialog, QHBoxLayout, QWidget from PyQt5 import QtGui from PyQt5.QtGui import QPainter,QBrush,QPen from PyQt5 import QtCore class Window(QMainWindow): def __init__(self): super().__init__() title = "Main Window";left=100;top=100;width=1200;height=800 self.setWindowTitle(title) self.setGeometry(left,top,width,height) self.Create_Button() self.show() def Create_Button(self): button = QPushButton("Click", self) button.setGeometry(30,100,200,80) button.clicked.connect(self.SecondWin) # 示例:把绘图Widget加入Box Layout layout = QHBoxLayout() central_widget = QWidget() self.setCentralWidget(central_widget) central_widget.setLayout(layout) draw_widget = QWidget() draw_widget.setFixedSize(300, 300) def widget_paint(event): painter = QPainter(draw_widget) painter.setPen(QPen(QtCore.Qt.blue, 4)) painter.drawRect(50,50,200,200) draw_widget.paintEvent = widget_paint layout.addWidget(draw_widget) layout.addWidget(button) def paintEvent(self,event): painter = QPainter(self) painter.setPen(QPen(QtCore.Qt.red,6,QtCore.Qt.SolidLine)) painter.setBrush(QBrush(QtGui.QColor(45,171,200),QtCore.Qt.SolidPattern)) painter.drawEllipse(550,150,300,600) def SecondWin(self): mydialog = QDialog(self) mydialog.setWindowTitle("Second Window") mydialog.setGeometry(400,200,600,300) # 动态绑定QDialog的paintEvent def dialog_paint_event(event): painter = QPainter(mydialog) painter.setPen(QPen(QtCore.Qt.red,6,QtCore.Qt.SolidLine)) painter.setBrush(QBrush(QtGui.QColor(45,171,200),QtCore.Qt.SolidPattern)) painter.drawEllipse(150, 50, 300, 200) mydialog.paintEvent = dialog_paint_event mydialog.show() App = QApplication(sys.argv) window = Window() sys.exit(App.exec_())
内容的提问来源于stack exchange,提问作者Nepura
相关产品推荐
相关产品推荐

