[英]Fixing Threads in PySide2
我使用 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>
親切的問候
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.