PyQt: Progress bar and label disappear
<p>I am new to Python and PyQt. When I start my program, after a few seconds, the progress bar and label disappear. The progress bar starts appearing and disappearing (the label is gone) when the mouse hovers over the progress bar, showing up once more before disappearing. But if I comment the line where I set up the progress bar value, the label does not disappear.</p>

<p>Here is the code:</p>

<pre><code>from PyQt4 import QtCore, QtGui, Qt
from PyQt4.Qt import QDialog, QApplication
import sys
import sensors
from sensors import *
import threading

class tmp():
    def main(self):
        global test
        global name
        sensors.init()
        try:
            for chip in sensors.iter_detected_chips():
                #print (chip)
                #print('Adapter:', chip.adapter_name)
                for feature in chip:
                    if feature.label == 'Physical id 0':
                        test = feature.get_value()
                        name = feature.label
                        #print ('%s (%r): %.1f' % (feature.name, feature.label, feature.get_value()))
                        threading.Timer(5.0, self.main).start()
                        return test
                print
        finally:
            sensors.cleanup()

zz = tmp()
zz.main()

class MainWindow(QtGui.QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setGeometry(50, 50, 250, 150)
        self.setWindowTitle("Title here")

        #lay = QtGui.QVBoxLayout()
        #lay.addWidget(self.prgB)
        #lay.addWidget(self.lbl)
        #self.setLayout(lay)

        self.home()

    def home(self):
        self.prgB = QtGui.QProgressBar(self)
        self.prgB.setGeometry(20, 20, 210, 20)

        self.lbl = QtGui.QLabel(self)
        self.lbl.setGeometry(20, 40, 210, 20)

        lay = QtGui.QVBoxLayout()
        lay.addWidget(self.prgB)
        lay.addWidget(self.lbl)
        self.setLayout(lay)
        self.update()

    def update(self):
        textas = ('%s : %.1f' % (name, test))
        self.lbl.setText(str(textas))
        self.prgB.setValue(test)
        threading.Timer(5.0, self.update).start()

        QtGui.QApplication.processEvents()

        self.show()

def run():    
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads)    
    app = QtGui.QApplication(sys.argv)
    GUI = MainWindow()        
    sys.exit(app.exec_())

run()
</code></pre>

<p>What I am trying to do is just get the temp value (pysensors) and pass it to the label text and progress bar value. It is working, just as I said, but after a few seconds the label is gone and the progress bar disappears.
I know (or I guess) there is something wrong with the update function. I just can't find out whats wrong.</p>

<p>First of all you don't need the separate class tmp(). Delete it and just move the main() function in MainWindow class. After doing this name,test variables should not be global any more. Define them in your <strong>init</strong> (for example self.test = 0, self.name='something') and refer to them in the rest of the code as self.test and self.name.</p>

<p>Now the most important mistake in your code is that you are trying to update GUI components from a different thread. GUI components should be handled only by the main thread using the signal/slot mechanism that pyqt provides.</p>

<p>The steps for doing this in your case are</p>

<ol>
<li>Define a new signal in MainWindow class</li>
<li>Connect this signal to the update() function</li>
<li>Emit this signal from main() function</li>
</ol>

<p>In the end your code should look like this</p>

<pre><code>class MainWindow(QtGui.QWidget):
    signalUpdateBar = QtCore.pyqtSignal()
    def __init__(self):
        ...
        self.test = 0
        self.name = "0"
        ...
    def home(self):
        ...
        self.signalUpdateBar.connect(self.update)
        self.main()
        self.show()

    def main():
        try:
            ...
            self.test = feature.get_value()
            self.name = feature.label
            threading.Timer(5.0, self.main).start()
            self.signalUpdateBar.emit()
        finally:
            ...
</code></pre>

<p>Moreover in your update() function </p>

<pre><code> self.prgB.setValue(self.test)
</code></pre>

<p>should be the last statement. Anything below that is not necessary.</p>

python multithreading python-2.7 pyqt