Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-674

Threaded app gets recursionerrors and doesnt work properly when compiled with cython and nuitka but works perfectly in python

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Not Evaluated
    • Resolution: Out of scope
    • Affects Version/s: 5.9, 5.11
    • Fix Version/s: None
    • Component/s: PySide
    • Labels:
      None
    • Environment:
      python 3.6, qt5.10.1, cython 0.28.2, tried both 5.9 and 5.11 from http://download.qt.io/snapshots/ci/pyside/

      Description

      edit: indented it now.

      This code will work perfectly before you compile it with cython or nuitka. If you compile it with cython it will output: ('thread1:', <Response [200]>) RecursionError: maximum recursion depth exceeded while calling a Python object and hang but it will show the window contents. With nuitka it will never show the contents of the window but the threads will run as expected. If you convert it to PyQt5 it will work perfectly even when compiled, but i can't use pyqt5 because the whole reason im using pyside2 is because of the license in the first place... I'd assume a lot of people using pyside2 is because of that and currently it doesn't seem like if one wants to compile an app with threads, that it works, so that has to be pretty bad...

      from PySide2 import QtCore, QtGui, QtWidgets
      from PySide2.QtCore import Slot, Signal, QThread
      import sys
      import requests
      import time
      
      class Ui_MainWindow(object):
          def setupUi(self, MainWindow):
              MainWindow.setObjectName("MainWindow")
              MainWindow.resize(800, 600)
              self.centralwidget = QtWidgets.QWidget(MainWindow)
              self.centralwidget.setObjectName("centralwidget")
              self.pushButton = QtWidgets.QPushButton(self.centralwidget)
              self.pushButton.setGeometry(QtCore.QRect(240, 100, 97, 34))
              self.pushButton.setObjectName("pushButton")
              self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
              self.plainTextEdit.setGeometry(QtCore.QRect(200, 160, 451, 271))
              self.plainTextEdit.setPlainText("")
              self.plainTextEdit.setObjectName("plainTextEdit")
              MainWindow.setCentralWidget(self.centralwidget)
              self.menubar = QtWidgets.QMenuBar(MainWindow)
              self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 30))
              self.menubar.setObjectName("menubar")
              MainWindow.setMenuBar(self.menubar)
              self.statusbar = QtWidgets.QStatusBar(MainWindow)
              self.statusbar.setObjectName("statusbar")
              MainWindow.setStatusBar(self.statusbar)
      
              self.retranslateUi(MainWindow)
              QtCore.QMetaObject.connectSlotsByName(MainWindow)
      
          def retranslateUi(self, MainWindow):
              _translate = QtCore.QCoreApplication.translate
              MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
              self.pushButton.setText(_translate("MainWindow", "OK"))
      
      class MainUIClass(QtWidgets.QMainWindow, Ui_MainWindow):
          def closeEvent(self, evnt):
              print("CLOSED")
              self.thread1.quit()
              self.thread2.quit()
              self.thread3.quit()
              self.thread1.wait()
              self.thread2.wait()
              self.thread3.wait()
              print("thread1 is running?:", self.thread1.isRunning())
              print("thread2 is running?:", self.thread2.isRunning())
              print("thread3 is running?:", self.thread3.isRunning())
              sys.exit()
              
          def __init__(self, parent=None):
              super().__init__()
              self.setupUi(self)
      
              self.thread1 = QThread()
              self.thread2 = QThread()
              self.thread3 = QThread()
      
              self.Class1 = Class1()
              self.Class2 = Class2()
              self.Class3 = Class3()
      
              self.Class1.moveToThread(self.thread1)
              self.Class2.moveToThread(self.thread2)
              self.Class3.moveToThread(self.thread3)
      
              self.thread1.started.connect(lambda: self.Class1.startThread())
      
              self.Class1.startThread2.connect(self.Class2.startThread)
              self.Class2.startThread3.connect(self.Class3.startThread)
              self.Class3.startThread1.connect(self.Class1.startThread)
      
              self.thread1.start()
              self.thread2.start()
              self.thread3.start()
      
      class Class1(QtCore.QObject):
          startThread2 = Signal()
      
          def __init__(self):
              super().__init__()
      
          @Slot()
          def startThread(self):
              time.sleep(1)
              #data = requests.get("https://www.google.com")
              data = "lel"
              print("thread1:", data)
              self.startThread2.emit()
      
      class Class2(QtCore.QObject):
          startThread3 = Signal()
      
          def __init__(self):
              super().__init__()
      
          @Slot()
          def startThread(self):
              time.sleep(1)
              #data = requests.get("https://www.google.com")
              data = "lel"
              print("thread2:", data)
              self.startThread3.emit()
      
      class Class3(QtCore.QObject):
          startThread1 = Signal()
      
          def __init__(self):
              super().__init__()
      
          @Slot()
          def startThread(self):
              time.sleep(1)
              #data = requests.get("https://www.google.com")
              data = "lel"
              print("thread3:", data)
              self.startThread1.emit()
      
      a = QtWidgets.QApplication(sys.argv)
      app = MainUIClass()
      
      a.setQuitOnLastWindowClosed(False)
      app.setWindowTitle("Pyside2 thread compiled test")
      app.show()
      
      sys.exit(a.exec_())
      

       

        Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            • Assignee:
              ctismer Christian Tismer
              Reporter:
              harrylop Harry Lop
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Gerrit Reviews

                There are no open Gerrit changes