为什么在pyqt5中使用滑块时程序关闭?

2024-05-13 09:35:49 发布

您现在位置:Python中文网/ 问答频道 /正文

为什么在pyqt5中使用滑块时程序关闭?它正常启动,但使用滑块后关闭。我必须使用第二个窗口中的滑块来改变第一个窗口中圆圈的大小。这是我的全部代码,因为我不知道会出什么问题。 enter image description here

from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPainter, QBrush, QPen
from PyQt5.QtCore import Qt
import sys


class ThirdWindow(QWidget):
    def __init__(self):
        super().__init__()
        hbox = QHBoxLayout()

        sld = QSlider(Qt.Horizontal, self)
        sld.setRange(0, 100)
        sld.setFocusPolicy(Qt.NoFocus)
        sld.setPageStep(5)

        sld.valueChanged.connect(self.updateLabel)

        self.label = QLabel('0', self)
        self.label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
        self.label.setMinimumWidth(80)

        hbox.addWidget(sld)
        hbox.addSpacing(15)
        hbox.addWidget(self.label)

        self.setLayout(hbox)

        self.setGeometry(600, 60, 500, 500)
        self.setWindowTitle('QSlider')
        self.show()

    def updateLabel(self, value):
        self.label.setText(str(value))
        self.parentWidget().radius = value
        self.parentWidget().repaint()


class Window(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setWindowTitle("Dialogi")
        self.w = ThirdWindow()
        actionFile = self.menuBar().addMenu("Dialog")
        action = actionFile.addAction("Zmień tło")
        action1 = actionFile.addAction("Zmień grubość koła")
        action1.triggered.connect(self.w.show)
        self.setGeometry(100, 60, 300, 300)
        self.setStyleSheet("background-color: Green")
        self.radius = 100  # add a variable radius to keep track of the circle radius

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setPen(QPen(Qt.gray, 8, Qt.SolidLine))
        # change function to include radius
        painter.drawEllipse(100, 100, self.radius, self.radius)


app = QApplication(sys.argv)
screen = Window()
screen.show()
sys.exit(app.exec_())

Tags: fromimportselfinitvaluedefshowsys
1条回答
网友
1楼 · 发布于 2024-05-13 09:35:49

parentWidget允许访问声明为Qt的父级的小部件

使用self.w = ...创建对象并不会使该对象成为父对象(self)的子对象,您只是创建对该对象的引用(w

如果在终端/提示符下运行程序,您将清楚地看到以下回溯:

Exception "unhandled AttributeError"
'NoneType' object has no attribute 'radius'

NoneType引用了parentWidget()的结果,由于没有实际设置父项,因此它返回None

如果您正确地设置了小部件的父对象(通过将父对象添加到小部件构造函数,或使用^{),您可以使用^{),但考虑到程序的结构,这不是一个好的选择,通常最好避免直接从“子对象”更改“父对象”:Qt的信号/插槽机制正是为了面向对象编程的模块化,因为孩子不应该真正“关心”自己的父母

解决方案是从“父项”连接到滑块,并从那里更新它

class ThirdWindow(QWidget):
    def __init__(self):
        # ...
        # make the slider an *instance member*, so that we can easily access it
        # from outside
        self.slider = QSlider(Qt.Horizontal, self)
        # ...


class Window(QMainWindow):
    def __init__(self):
        # ...
        self.w.slider.valueChanged.connect(self.updateLabel)

    def updateLabel(self, value):
        self.radius = value
        self.update()

显然,您需要删除ThirdWindow类中的valueChanged连接,因为您不再需要它了。
还要注意,您很少需要repaint(),而update()应该是首选

相关问题 更多 >