PyQt5与线程和进度条崩溃

时间:2017-03-17 05:22:14

标签: python-3.x pyqt pyqt5 python-multithreading

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

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 个答案:

答案 0 :(得分:0)

  

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_())

如果您想在多线程之间进行通信,可以尝试使用signal / slots。