You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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画的椭圆)不是控件。不过我们可以用间接的方法实现:

  1. 自定义QWidget承载绘图:创建一个QWidget子类,在它的paintEvent里绘制几何图形,然后把这个自定义Widget添加到Box Layout中。
  2. 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:37:58