0

I've been writing a program that used a MyWindow(QTableWidget) with a thread. A progress bar is displayed above the sub-window(self.win) displayed as a pop-up.

I want a green bar on the status bar to be displayed consecutively, however after resetting the Spyder-kernel, the green bar does not output continuously. And I want to run the 'stop'/'continue' alternately every time I click the push button. This hasn't been resolved for almost three days.

import sys, time
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot, QRect
from PyQt5.QtWidgets import *

progVal = 0

class thread(QThread):
    
    signalTh = pyqtSignal(int)
    
    def __init__(self, *args):
        super().__init__()
        self.flag = True
        
    def run(self):
        global progVal
        if self.flag:
            self.signalTh.emit(progVal)
            time.sleep(0.1)
            
    def stop(self):
        self.flag = False
        self.quit()
        self.wait(2)

class MyWindow(QTableWidget):
    def __init__(self):
        global progVal
        super().__init__()
        self.setupUi()
        self.show()

        self.test = thread(None)
        self.test.signalTh.connect(self.signal_function)
        self.test.run()
        self.saveData()

    def saveData(self):   
        global progVal
        counts = range(1, 51)
        for row in counts:
            progVal = int(row/len(counts)*100) 
            self.test.signalTh.emit(progVal)
            time.sleep(0.1)

    def click1_function(self):

        if self.test.flag:
            self.test.stop()
            self.pb_start.setText('Start!')
        else:
            self.test.flag = True
            self.test.run()
            self.pb_start.setText('Stop!')

    @pyqtSlot(int)
    def signal_function(self, val):
        self.progress.setValue(val)
        self.progress.update()
        self.win.update()
        self.update()

    def setupUi(self):
        self.resize(500, 400)
        self.pb_start = QPushButton(self)
        self.pb_start.setGeometry(QRect(80, 20, 100, 50))
        self.pb_start.setText("Start")
        self.pb_start.clicked.connect(self.click1_function)

        self.win = QDialog(self)
        self.win.resize(330, 100)
        self.progress = QProgressBar(self.win)
        self.progress.setGeometry(10, 10, 300, 30)
        self.progress.setMaximum(100)        
        self.win.show()
        
    def closeEvent(self, event):
        quit_msg = "Are you sure you want to exit the program?"
        reply = QMessageBox.question(self, 'Message', quit_msg, QMessageBox.Yes, QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.test.stop()
            event.accept()
        else:
            event.ignore()
            
if __name__ == "__main__":
    app = QApplication(sys.argv)
    myApp = MyWindow()
    myApp.show()
    app.exec_()

capture 1

enter image description here

karel
  • 5,489
  • 46
  • 45
  • 50
Happy_win
  • 1
  • 2
  • You're not supposed to call `run()` directly, because if you do that you're *not* using the thread. Change that to `self.test.start()`. Also, do not use globals, and remove `saveData`, which is blocking and should also *not* emit a signal that it doesn't actually own. – musicamante May 11 '22 at 16:14
  • Thank you so much for your reply. I used the start() function first, but it didn't work. And the saveData function was written in the __init__() function, but it didn't work. What I want is to express the progress rate of the data being stored in progress bar. Thank you again. – Happy_win May 11 '22 at 23:14
  • It didn't work because `run()` does only one function call and exits. You have to put the `for` loop there. Also remove all those `update()` calls in `signal_function`, as they are pointless. – musicamante May 11 '22 at 23:49

0 Answers0