Reputation: 3733
I have the following two files:
import sys
import time
from PyQt4 import QtGui, QtCore
import btnModule
class WindowClass(QtGui.QWidget):
def __init__(self):
super(WindowClass, self).__init__()
self.dataLoaded = None
# Widgets
# Buttons
thread = WorkerForLoop(self.runLoop)
# thread.start()
self.playBtn = btnModule.playpauselBtnClass \
('Play', thread.start)
# Layout
layout = QtGui.QHBoxLayout()
layout.addWidget(self.playBtn)
self.setLayout(layout)
# Window Geometry
self.setGeometry(100, 100, 100, 100)
def waitToContinue(self):
print self.playBtn.text()
while (self.playBtn.text() != 'Pause'):
pass
def runLoop(self):
for ii in range(100):
self.waitToContinue()
print 'num so far: ', ii
time.sleep(0.5)
class WorkerForLoop(QtCore.QThread):
def __init__(self, function, *args, **kwargs):
super(WorkerForLoop, self).__init__()
self.function = function
self.args = args
self.kwargs = kwargs
def __del__(self):
self.wait()
def run(self):
print 'let"s run it'
self.function(*self.args, **self.kwargs)
return
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
wmain = WindowClass()
wmain.show()
sys.exit(app.exec_())
and the second file btnModule.py:
from PyQt4 import QtGui, QtCore
class playpauselBtnClass(QtGui.QPushButton):
btnSgn = QtCore.pyqtSignal()
def __init__(self, btnName, onClickFunction):
super(playpauselBtnClass, self).__init__(btnName)
self.clicked.connect(self.btnPressed)
self.btnSgn.connect(onClickFunction)
def btnPressed(self):
if self.text() == 'Play':
self.setText('Pause')
self.btnSgn.emit()
print 'Changed to pause and emited signal'
elif self.text() == 'Pause':
self.setText('Continue')
print 'Changed to Continue'
elif self.text() == 'Continue':
self.setText('Pause')
print 'Changed to Pause'
If in the first file I remove the comment at thread.start()
it works as expected, it starts the thread and then hangs until I click Play
on the UI. However, I thought it should work even if I didn't start it there as the signal is btnSgn
is connected to onClickFunction
which in this case takes the value thread.start
.
Used this as a reference http://joplaete.wordpress.com/2010/07/21/threading-with-pyqt4/
Upvotes: 0
Views: 128
Reputation: 497
I think the reason it doesn't work when you try to call thread.start() in your second file (via self.btnSgn.emit()) is that the thread object goes out of scope outside of the init function where you created it. So you are calling start() on an already deleted thread.
Just changing thread -> self.thread (i.e. making the thread object a member of the WindowClass object) works fine when I tried it, since thread is then kept alive till the end of the program.
Upvotes: 2