PySide2中的固定线程

问题描述 投票:0回答:1

我已经使用PySide2编写了一个具有800行代码的应用程序,现在,当我想在进度栏中显示一个变量时,它在短时间内崩溃而没有任何警告。默默。刚才我突然意识到,我构建此GUI的整个方法可能是错误的。可以以某种方式保存此代码,以便它可以通过信号从线程内部设置此进度条而不会导致应用程序崩溃吗?

编辑:这个最小的代码可以工作并崩溃,但是需要一个小的ui文件。只需将下面的第二个代码复制到记事本中,并将其另存为“ test_minim.ui”。一分钟后它可能崩溃,没有任何警告。

import time
import os
import sys
import tempfile
import pkgutil
import numpy as np

import threading

from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication, QPushButton, QLineEdit, QProgressBar
from PySide2.QtCore import QFile, QObject, QThread
from PySide2.QtGui import qApp

class MyMainWindow(QObject):

    def __init__(self, ui_file, parent=None):
        super(MyMainWindow, self).__init__(parent)

        self.my_package_name = "test_minim"

        self.window = self.load_ui("test_minim.ui")

        self.startButton  = self.window.findChild(QPushButton, 'startButton')
        self.startButton.clicked.connect(self.start)

        self.stopButton  = self.window.findChild(QPushButton, 'stopButton')
        self.stopButton.clicked.connect(self.stop)

        self.colCentral  = self.window.findChild(QProgressBar, 'colCentral')

        self.newLSF = False
        self.LSF = 0

        self.run = False


    def load_ui(self, filename):
        # We might run from a PYZ file, but QUiLoader requires a plain file,
        # so extract it to a temporary file.
        temp = tempfile.NamedTemporaryFile(delete=False)
        temp.write(pkgutil.get_data(self.my_package_name, filename))
        temp.close()
        ui_file = QFile(temp.name)    
        ui = QUiLoader().load(ui_file)    
        ui_file.close()
        ui_file.remove()

        return ui

    def show(self):
        print("Showing...")
        self.window.show()        


    def start(self):
        self.run = True
        calculateLSFThread = threading.Thread(None, self.calculateLSF)
        displayThread = threading.Thread(None, self.displayBar)

        calculateLSFThread.start()
        displayThread.start()

    def calculateLSF(self):
       while self.run:
           time.sleep(0.3)
           #some processing goes here
           #takes a while to compute
           self.LSF = 50 + int(80*(np.random.rand(1)-0.5))
           self.newLSF = True 

    def displayBar(self):
       while self.run == True:
           if not self.newLSF:
               time.sleep(0.01)
           else:
               self.colCentral.setValue(self.LSF)
               self.newLSF = False
    def stop(self):
        self.run = False

def start_gui():


    app = QApplication.instance()
    if not app:
        # Instanciate QApplication singleton if it doesn't exist. It might
        # already exist, for instance starting application again in Spyder
        # in the same IPython shell
        app = QApplication(sys.argv)
    main_window = MyMainWindow("prime_gui.ui")
    main_window.show()
    return app.exec_()


if __name__ == '__main__':
    start_gui()

此处打开了用于记事本的ui文件。需要保存为“ test_minim.ui”。

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>289</width>
    <height>531</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <property name="windowOpacity">
   <double>1.000000000000000</double>
  </property>
  <property name="layoutDirection">
   <enum>Qt::LeftToRight</enum>
  </property>
  <property name="animated">
   <bool>false</bool>
  </property>
  <property name="tabShape">
   <enum>QTabWidget::Rounded</enum>
  </property>
  <property name="dockOptions">
   <set>QMainWindow::AllowTabbedDocks</set>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="startButton">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>40</y>
      <width>71</width>
      <height>23</height>
     </rect>
    </property>
    <property name="autoFillBackground">
     <bool>false</bool>
    </property>
    <property name="text">
     <string>Start </string>
    </property>
    <property name="checkable">
     <bool>false</bool>
    </property>
   </widget>
   <widget class="QPushButton" name="stopButton">
    <property name="enabled">
     <bool>true</bool>
    </property>
    <property name="geometry">
     <rect>
      <x>160</x>
      <y>40</y>
      <width>71</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>Stop</string>
    </property>
   </widget>
   <widget class="QGroupBox" name="groupBoxMTF">
    <property name="geometry">
     <rect>
      <x>40</x>
      <y>90</y>
      <width>192</width>
      <height>301</height>
     </rect>
    </property>
    <property name="title">
     <string>LTF</string>
    </property>
    <layout class="QGridLayout" name="gridLayout_3">
     <item row="0" column="0" colspan="2">
      <layout class="QGridLayout" name="layoutDisplayMTF">
       <item row="0" column="0">
        <widget class="QProgressBar" name="colCentral">
         <property name="maximum">
          <number>100</number>
         </property>
         <property name="value">
          <number>0</number>
         </property>
         <property name="textVisible">
          <bool>true</bool>
         </property>
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="invertedAppearance">
          <bool>false</bool>
         </property>
         <property name="textDirection">
          <enum>QProgressBar::TopToBottom</enum>
         </property>
        </widget>
       </item>
      </layout>
     </item>
    </layout>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>289</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

亲切的问候

python multithreading pyqt pyside qthread
1个回答
0
投票

尝试使用QThreads而不是常规线程。它们的工作方式非常相似,但是它们提供了对UI线程的线程安全调用。

Example

© www.soinside.com 2019 - 2024. All rights reserved.