简体   繁体   中英

Why my program is closing when I am using Slider in pyqt5?

Why my program is closing when I am using Slider in pyqt5? It starts normal but after using Slider it close. I have to change size of circle in first window by using Slider from second window. This is my full code, beacuse I don't know what could be wrong. 在此处输入图像描述

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_())

parentWidget allows access to a widget declared as parent for Qt .

Creating an object using self.w =... doesn't make that object a child of the parent ( self ), you are only creating a reference ( w ) to it.

If you run your program in a terminal/prompt you'll clearly see the following traceback:

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

The NoneType refers to the result of parentWidget() , and since no parent has been actually set, it returns None .

While you could use parentWidget if you correctly set the parent for that widget (by adding the parent to the widget constructor, or using setParent() ), considering the structure of your program it wouldn't be a good choice, and it's usually better to avoid changes to a "parent" object directly from the "child": the signal/slot mechanism of Qt is exactly intended for the modularity of Object Oriented Programming, as a child should not really "care" about its parent.

The solution is to connect to the slider from the "parent", and update it from there.

class ThirdWindow(QWidget):
    def __init__(self):
        # ...
        # make the slider an *instance member*, so that we can easily access it
        # from outside
         = 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()

You obviously need to remove the valueChanged connection in the ThirdWindow class, as you don't need it anymore.
Also note that you rarely need repaint() , and update() should be preferred instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM