Python Forum
[PyQt] Received RunTimeError after script concludes, closing Dialog Window (clicking x-out)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] Received RunTimeError after script concludes, closing Dialog Window (clicking x-out)
#1
Greetings All,
In learning more about using PyQt5's signals and slots I found a tutorial here. I pasted the code segments into my editor and ran it...(seems to run fine.) However, when I closed the dialog by clicking out, I received the following error:
Error:
[Command: python -u C:\Users\erica\AppData\Local\Programs\Python\Python37\scripts_PyQt5.py] Exception ignored in: <function Worker.__del__ at 0x0000016663FA1EA0> Traceback (most recent call last): File "C:\Users\erica\AppData\Local\Programs\Python\Python37\scripts_PyQt5.py", line 4250, in __del__ RuntimeError: wrapped C/C++ object of type Worker has been deleted [Finished in 52.375s]
I found a stackoverflow post (SO) which seems to summarize how Python and PyQt5 address the (owner semantics, object deletion) as related to C/C++ wrappers, etc. I'm still trying to learn the ideas/lessons presented.

My questions:
  • Is this error caused by something in the code (like the __del__ function) or garbage collection, or (some) object.__init__?
  • Would the super() function be a more current function to use instead of the explicit "QThread.__init__(self, parent)" for example?
  • Am I correct in thinking that the Worker() object has a parent and that a reference is kept?
  • Would a try/except block be appropriate to catch/manage this type of error?

My code as drawn from the tutorial (apologize for the line numbers):
# 2nd PyQt5 Threading and Slots per https://wiki.python.org/moin/PyQt5/Threading%2C_Signals_and_Slots

import math, random, sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class Window(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.thread = Worker()

        label = QLabel(self.tr("Number of stars:"))
        self.spinBox = QSpinBox()
        self.spinBox.setMaximum(10000)
        self.spinBox.setValue(100)
        self.startButton = QPushButton(self.tr("&Start"))
        self.viewer = QLabel()
        self.viewer.setFixedSize(300, 300)

        self.thread.finished.connect(self.updateUi)
        # self.thread.terminated.connect(self.updateUi)
        self.thread.output['QRect', 'QImage'].connect(self.addImage)
        self.startButton.clicked.connect(self.makePicture)

        layout = QGridLayout()
        layout.addWidget(label, 0, 0)
        layout.addWidget(self.spinBox, 0, 1)
        layout.addWidget(self.startButton, 0, 2)
        layout.addWidget(self.viewer, 1, 0, 1, 3)
        self.setLayout(layout)
        self.setWindowTitle(self.tr("Simple Threading Example"))

    def makePicture(self):
        self.spinBox.setReadOnly(True)
        self.startButton.setEnabled(False)
        pixmap = QPixmap(self.viewer.size())
        pixmap.fill(Qt.black)
        self.viewer.setPixmap(pixmap)
        self.thread.render(self.viewer.size(), self.spinBox.value())

    def addImage(self, rect, image):
        pixmap = self.viewer.pixmap()
        painter = QPainter()
        painter.begin(pixmap)
        painter.drawImage(rect, image)
        painter.end()
        self.viewer.update(rect)

    def updateUi(self):
        self.spinBox.setReadOnly(False)
        self.startButton.setEnabled(True)

class Worker(QThread):
    output = pyqtSignal(QRect, QImage)

    def __init__(self, parent = None):
        QThread.__init__(self, parent)
        self.exiting = False
        self.size = QSize(0, 0)
        self.stars = 0

        self.path = QPainterPath()
        angle = 2*math.pi/5
        self.outerRadius = 20
        self.innerRadius = 8
        self.path.moveTo(self.outerRadius, 0)
        for step in range(1, 6):
            self.path.lineTo(
                self.innerRadius * math.cos((step - 0.5) * angle),
                self.innerRadius * math.sin((step - 0.5) * angle)
                )
            self.path.lineTo(
                self.outerRadius * math.cos(step * angle),
                self.outerRadius * math.sin(step * angle)
                )
        self.path.closeSubpath()

    def __del__(self):
        self.exiting = True
        self.wait()

    def render(self, size, stars):
        self.size = size
        self.stars = stars
        self.start()

    def run(self):
        # Note: This is never called directly. It is called by Qt once the
        # thread environment has been set up.
        random.seed()
        n = self.stars
        width = self.size.width()
        height = self.size.height()

        while not self.exiting and n > 0:
            image = QImage(self.outerRadius * 2, self.outerRadius * 2, QImage.Format_ARGB32)
            image.fill(qRgba(0, 0, 0, 0))
            x = random.randrange(0, width)
            y = random.randrange(0, height)
            angle = random.randrange(0, 360)
            red = random.randrange(0, 256)
            green = random.randrange(0, 256)
            blue = random.randrange(0, 256)
            alpha = random.randrange(0, 256)

            painter = QPainter()
            painter.begin(image)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setPen(Qt.NoPen)
            painter.setBrush(QColor(red, green, blue, alpha))
            painter.translate(self.outerRadius, self.outerRadius)
            painter.rotate(angle)
            painter.drawPath(self.path)
            painter.end()

            self.output.emit( QRect(x - self.outerRadius, y - self.outerRadius, self.outerRadius * 2, self.outerRadius * 2), image)
            n -= 1

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
I do appreciate your time and comments... thank you very much.

My environment:
Windows 10 Home, version 10.0.19041 Build 19041, x64
Atom 1.50.0 x64 with script 3.26.0 package
Python 3.7 (64-bit)
PyQt5 version 5.15.0
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Closing window on button click not working kenwatts275 4 463 May-03-2020, 01:59 PM
Last Post: deanhystad
  Need tkinter help with clicking buttons pythonprogrammer 2 518 Jan-03-2020, 04:43 AM
Last Post: joe_momma
  tkinter window and turtle window error 1885 3 1,630 Nov-02-2019, 12:18 PM
Last Post: 1885
  [WxPython] Return code when closing the dialog ioprst 1 944 Aug-13-2019, 11:47 AM
Last Post: jefsummers
  PyQT5 : Unable to Create Another Dialog While One is Open iMuny 3 847 Jul-17-2019, 11:40 AM
Last Post: iMuny
  [split] Closing a window but not the whole program scriptdrache 1 551 Jun-25-2019, 03:43 PM
Last Post: joe_momma
  tkinter- adding a new window after clicking a button built on the gui ShashankDS 2 3,215 Apr-18-2019, 12:48 PM
Last Post: ShashankDS
  [WxPython] Any dialog that allow user to select file OR folder? buran 3 1,223 Apr-03-2019, 06:33 PM
Last Post: Yoriz
  [Tkinter] Closing a window but not the whole program Wiggy1 2 1,296 Jan-11-2019, 12:51 AM
Last Post: Larz60+
  [WxPython] how to run the dialog from another py file royer14 0 1,071 Jul-02-2018, 05:33 AM
Last Post: royer14

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020