【问题标题】:PyQt5 Multithreading Crashes with No Console ErrorPyQt5 多线程崩溃,没有控制台错误
【发布时间】:2023-03-17 12:54:02
【问题描述】:

我有一个正在工作的项目。由于项目的性质,我无法分享所有代码。

下面是我尝试在按钮单击时实现线程的代码。

from PyQt5 import QtCore, QtWidgets, QtGui, QtSerialPort
from PyQt5 import uic
import sys, time

class BETA_THREADED(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.ui = uic.loadUi('rocket_3.ui', self)
        # self.resize(1920, 1080)

        self.thread={}
        self.launchButton.clicked.connect(self.start_worker)
        self.abortButton.clicked.connect(self.stop_worker)

    def start_worker(self):
        print('1')
        self.thread[1] = ThreadClass(parent = None, index = 1)
        self.thread[1].start()
        self.thread[1].any_signal.connect(self.launchSequence)
        self.launchButton.setEnabled(False)

    def stop_worker(self):
        self.thread[1].stop()
        self.launchButton.setEnabled(True)

    def launchSequence(self):
        print('Test')

class ThreadClass(QtCore.QThread):
    
    any_signal = QtCore.pyqtSignal(int)
    def __init__(self, parent=None,index=0):
        super(ThreadClass, self).__init__(parent)
        self.index=index
        self.is_running = True
    def run(self):
        print('Starting thread...',self.index)
        cnt=0
        while (True):
            cnt+=1
            if cnt==99: cnt=0
            time.sleep(0.01)
            self.any_signal.emit(cnt) 
    def stop(self):
        self.is_running = False
        print('Stopping thread...',self.index)
        self.terminate()

app = QtWidgets.QApplication(sys.argv)
mainWindow = BETA_THREADED()
mainWindow.show()
sys.exit(app.exec_())

UI文件由PyQt Designer生成,按钮为普通按钮。

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Rocket</class>
 <widget class="QMainWindow" name="Rocket">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1262</width>
    <height>323</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Rocket</string>
  </property>
  <property name="styleSheet">
   <string notr="true"/>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QTextBrowser" name="statusBar">
    <property name="geometry">
     <rect>
      <x>230</x>
      <y>220</y>
      <width>1011</width>
      <height>61</height>
     </rect>
    </property>
   </widget>
   <widget class="QLabel" name="label_6">
    <property name="geometry">
     <rect>
      <x>230</x>
      <y>190</y>
      <width>111</width>
      <height>17</height>
     </rect>
    </property>
    <property name="font">
     <font>
      <family>Carlito</family>
      <pointsize>14</pointsize>
     </font>
    </property>
    <property name="text">
     <string>STATUS</string>
    </property>
   </widget>
   <widget class="QGroupBox" name="groupBox">
    <property name="enabled">
     <bool>true</bool>
    </property>
    <property name="geometry">
     <rect>
      <x>-10</x>
      <y>-10</y>
      <width>221</width>
      <height>291</height>
     </rect>
    </property>
    <property name="title">
     <string/>
    </property>
    <property name="flat">
     <bool>false</bool>
    </property>
    <property name="checkable">
     <bool>false</bool>
    </property>
    <widget class="QPushButton" name="launchButton">
     <property name="geometry">
      <rect>
       <x>30</x>
       <y>60</y>
       <width>161</width>
       <height>101</height>
      </rect>
     </property>
     <property name="font">
      <font>
       <family>Carlito</family>
       <pointsize>14</pointsize>
      </font>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: blue;</string>
     </property>
     <property name="text">
      <string>LAUNCH</string>
     </property>
    </widget>
    <widget class="QPushButton" name="abortButton">
     <property name="geometry">
      <rect>
       <x>30</x>
       <y>180</y>
       <width>161</width>
       <height>101</height>
      </rect>
     </property>
     <property name="font">
      <font>
       <family>Carlito</family>
       <pointsize>14</pointsize>
      </font>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: red;</string>
     </property>
     <property name="text">
      <string>ABORT</string>
     </property>
    </widget>
   </widget>
  </widget>
 </widget>
 <tabstops>
  <tabstop>launchButton</tabstop>
  <tabstop>statusBar</tabstop>
  <tabstop>abortButton</tabstop>
 </tabstops>
 <resources/>
 <connections>
  <connection>
   <sender>launchButton</sender>
   <signal>clicked()</signal>
   <receiver>launchButton</receiver>
   <slot>click()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>546</x>
     <y>720</y>
    </hint>
    <hint type="destinationlabel">
     <x>546</x>
     <y>720</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>abortButton</sender>
   <signal>clicked()</signal>
   <receiver>abortButton</receiver>
   <slot>click()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>630</x>
     <y>910</y>
    </hint>
    <hint type="destinationlabel">
     <x>630</x>
     <y>910</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

当我运行文件时,我的窗口会按预期打开,然后在单击任何按钮时关闭。我终其一生都无法弄清楚为什么。

编辑:更正了拼写和其他错误,提供了 python 和 UI 的完整文件。该程序仍然在任何按钮单击时关闭,并且在 cmd 中没有错误。

【问题讨论】:

    标签: python user-interface pyqt5


    【解决方案1】:

    您在 Qt Designer 中连接信号时错误地指定了插槽

    import sys, time
    from PyQt5 import QtCore, QtWidgets, QtGui, QtSerialPort
    from PyQt5 import uic
    
    
    class Ui_Rocket(object):
        def setupUi(self, Rocket):
            Rocket.setObjectName("Rocket")
            Rocket.resize(1262, 323)
            Rocket.setStyleSheet("")
            self.centralwidget = QtWidgets.QWidget(Rocket)
            self.centralwidget.setObjectName("centralwidget")
            
            self.statusBar = QtWidgets.QTextBrowser(self.centralwidget)
            self.statusBar.setGeometry(QtCore.QRect(230, 220, 1011, 61))
            self.statusBar.setObjectName("statusBar")
            
            self.label_6 = QtWidgets.QLabel(self.centralwidget)
            self.label_6.setGeometry(QtCore.QRect(230, 190, 111, 17))
            font = QtGui.QFont()
            font.setFamily("Carlito")
            font.setPointSize(14)
            self.label_6.setFont(font)
            self.label_6.setObjectName("label_6")
            
            self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
            self.groupBox.setEnabled(True)
            self.groupBox.setGeometry(QtCore.QRect(-10, -10, 221, 291))
            self.groupBox.setTitle("")
            self.groupBox.setFlat(False)
            self.groupBox.setCheckable(False)
            self.groupBox.setObjectName("groupBox")
            
            self.launchButton = QtWidgets.QPushButton(self.groupBox)
            self.launchButton.setGeometry(QtCore.QRect(30, 60, 161, 101))
            font = QtGui.QFont()
            font.setFamily("Carlito")
            font.setPointSize(14)
            self.launchButton.setFont(font)
            self.launchButton.setStyleSheet("background-color: blue;")
            self.launchButton.setObjectName("launchButton")
            
            self.abortButton = QtWidgets.QPushButton(self.groupBox)
            self.abortButton.setGeometry(QtCore.QRect(30, 180, 161, 101))
            font = QtGui.QFont()
            font.setFamily("Carlito")
            font.setPointSize(14)
            self.abortButton.setFont(font)
            self.abortButton.setStyleSheet("background-color: red;")
            self.abortButton.setObjectName("abortButton")
            
            Rocket.setCentralWidget(self.centralwidget)
    
            self.retranslateUi(Rocket)
    #                                          ???????????????????????         
    #        self.launchButton.clicked.connect(self.launchButton.click)
    #        self.abortButton.clicked.connect(self.abortButton.click)
            
            QtCore.QMetaObject.connectSlotsByName(Rocket)
            Rocket.setTabOrder(self.launchButton, self.statusBar)
            Rocket.setTabOrder(self.statusBar, self.abortButton)
    
        def retranslateUi(self, Rocket):
            _translate = QtCore.QCoreApplication.translate
            Rocket.setWindowTitle(_translate("Rocket", "Rocket"))
            self.label_6.setText(_translate("Rocket", "STATUS"))
            self.launchButton.setText(_translate("Rocket", "LAUNCH"))
            self.abortButton.setText(_translate("Rocket", "ABORT"))
    
    
    class ThreadClass(QtCore.QThread):
        any_signal = QtCore.pyqtSignal(int)
    
        def __init__(self, parent=None, index=0):
            super(ThreadClass, self).__init__(parent)
            self.index=index
            self.is_running = True
        def run(self):
            print('Starting thread...',self.index)
            cnt=0
            while (True):
                cnt+=1
                if cnt==99: cnt=0
                time.sleep(0.01)
                self.any_signal.emit(cnt) 
        def stop(self):
            self.is_running = False
            print('Stopping thread...',self.index)
            self.terminate()
            
    
    class BETA_THREADED(QtWidgets.QMainWindow, Ui_Rocket):           # +++ , Ui_Rocket
        def __init__(self):
            super().__init__()
            
            self.setupUi(self)                                       # +++
            
    #        self.ui = uic.loadUi('rocket_3.ui', self)
            # self.resize(1920, 1080)
    
            self.thread = {}
            self.launchButton.clicked.connect(self.start_worker)
            self.abortButton.clicked.connect(self.stop_worker)
    
        def start_worker(self):
            print('111')
            
            self.thread[1] = ThreadClass(parent = None, index = 1)
            self.thread[1].start()
            self.thread[1].any_signal.connect(self.launchSequence)
            self.launchButton.setEnabled(False)
            
        def stop_worker(self):
            print('222')
            self.thread[1].stop()
            self.launchButton.setEnabled(True)
    
        def launchSequence(self):
            print('Test')
    
    
    app = QtWidgets.QApplication(sys.argv)
    mainWindow = BETA_THREADED()
    mainWindow.show()
    sys.exit(app.exec_())
    

    【讨论】:

      猜你喜欢
      • 2022-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-03
      • 1970-01-01
      • 2019-03-29
      相关资源
      最近更新 更多