2017-03-17 373 views
0

我有一个进度条,由一个开始停止按钮控制。进度条使用线程填充。然而,每当我运行程序时,它随机崩溃(每次运行程序的时间不同)。PyQt5崩溃的线程和进度条

class Window(QWidget): 
    def __init__(self): 
     super().__init__() 
     self.initUI() 
     self.fill_thread = None 

用于填充进度条的线程。我曾尝试使用time.sleep和QThread.msleep。

def fill_bar(self): 
    while not self.stop_fill and self.completed < 100: 
     self.completed += 0.5 
     QThread.msleep(100) 
     self.chargeprog.setValue(self.completed) 

按钮,开始之间交替,并停止调用线程

def charging(self): 
    if self.chargebtn.text() == 'Start': 
     self.chargebtn.setText('Stop') 
     self.chargebtn.setStyleSheet('background-color:red') 
     self.fill_thread = threading.Thread(target=self.fill_bar) 
     self.stop_fill = False 
     self.fill_thread.start() 
    else: 
     self.stop_fill = True 
     self.fill_thread.join() 
     self.chargebtn.setText('Start') 
     self.chargebtn.setStyleSheet('background-color:limegreen') 

回答

-1

window.py

# -*- coding: utf-8 -*- 

# Form implementation generated from reading ui file 'window.ui' 
# 
# Created by: PyQt5 UI code generator 5.6 
# 
# WARNING! All changes made in this file will be lost! 

from PyQt5 import QtCore, QtGui, QtWidgets 

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.progressBar = QtWidgets.QProgressBar(self.centralwidget) 
     self.progressBar.setGeometry(QtCore.QRect(180, 150, 118, 23)) 
     self.progressBar.setProperty("value", 24) 
     self.progressBar.setObjectName("progressBar") 
     self.pushButton = QtWidgets.QPushButton(self.centralwidget) 
     self.pushButton.setGeometry(QtCore.QRect(330, 150, 75, 23)) 
     self.pushButton.setObjectName("pushButton") 
     MainWindow.setCentralWidget(self.centralwidget) 
     self.menubar = QtWidgets.QMenuBar(MainWindow) 
     self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 18)) 
     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", "PushButton")) 

test.py

import sys 
from PyQt5.QtWidgets import QApplication,QMainWindow 
from PyQt5.QtCore import QThread,pyqtSignal 
from window import Ui_MainWindow 

class CThread(QThread): 
    valueChanged = pyqtSignal([int]) 
    def __init__(self,value): 
     super().__init__() 
     self.stop_fill = False 
     self.completed = value 

    def run(self): 
     while not self.stop_fill and self.completed < 100: 
      self.completed += 0.5 
      self.sleep(1) 
      self.valueChanged.emit(self.completed) 

class Window(QMainWindow,Ui_MainWindow): 
    def __init__(self): 
     super().__init__() 
     super().setupUi(self) 
     self.fill_thread = None 
     self.pushButton.clicked.connect(self.charging) 

    def charging(self): 
     if self.pushButton.text() == 'Start': 
      self.pushButton.setText('Stop') 
      self.pushButton.setStyleSheet('background-color:red') 
      print(self.progressBar.value()) 
      self.fill_thread = CThread(self.progressBar.value()) 
      self.fill_thread.valueChanged.connect(self.progressBar.setValue) 
      self.fill_thread.start() 
     else: 
      if self.fill_thread != None: 
       self.fill_thread.disconnect() # event unbind 
       self.fill_thread.stop_fill = True 
       self.fill_thread.wait() 
       self.fill_thread.quit() 
       print(self.fill_thread.isRunning()) 
      self.pushButton.setText('Start') 
      self.pushButton.setStyleSheet('background-color:limegreen') 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    w = Window() 
    w.show() 
    sys.exit(app.exec_()) 

如果你想在多线程之间进行通信,你可以尝试信号/插槽。