Issue
I have a PyQt GUI where the user presses a button to start a background thread (workerThread, which is subclassed from QThread). I would like to have a timer display (in the form of a QLabel) to show how much time has elapsed since workerThread started, and I would like this timer to stop as soon as the workerThread exits.
Possible solution
I've thought about creating another independent thread (timerThread) that uses a QTimer to send a signal to a slot to update the QLabel in the main GUI thread with the elapsed time every 1 second. This timerThread will exit as soon as it receives a terminate signal from workerThread.
However, I'd have to start timerThread at the same time as WorkerThread, and I'm not sure how to this.
Question
Is there an easier way to do this? Is QTimer even the right approach to start with?
Here is one way of doing this. In this example, myThread starts the timerThread as a child process when it's run method is called. It's timeElapsed signal is connected to the timerThreads timeElapsed signal. The timerThread will check each second while the parent isRunning and emit a timeElapsed signal if True:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import time
from PyQt4 import QtCore, QtGui
class timerThread(QtCore.QThread):
timeElapsed = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
super(timerThread, self).__init__(parent)
self.timeStart = None
def start(self, timeStart):
self.timeStart = timeStart
return super(timerThread, self).start()
def run(self):
while self.parent().isRunning():
self.timeElapsed.emit(time.time() - self.timeStart)
time.sleep(1)
class myThread(QtCore.QThread):
timeElapsed = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
super(myThread, self).__init__(parent)
self.timerThread = timerThread(self)
self.timerThread.timeElapsed.connect(self.timeElapsed.emit)
def run(self):
self.timerThread.start(time.time())
iterations = 3
while iterations:
print "Running {0}".format(self.__class__.__name__)
iterations -= 1
time.sleep(2)
class myWindow(QtGui.QWidget):
def __init__(self):
super(myWindow, self).__init__()
self.button = QtGui.QPushButton(self)
self.button.setText("Start Threading!")
self.button.clicked.connect(self.on_button_clicked)
self.label = QtGui.QLabel(self)
self.layout = QtGui.QVBoxLayout(self)
self.layout.addWidget(self.button)
self.layout.addWidget(self.label)
self.myThread = myThread(self)
self.myThread.timeElapsed.connect(self.on_myThread_timeElapsed)
self.myThread.finished.connect(self.on_myThread_finished)
#QtCore.pyqtSlot()
def on_button_clicked(self):
self.myThread.start()
#QtCore.pyqtSlot(int)
def on_myThread_timeElapsed(self, seconds):
self.label.setText("Time Elapsed: {0}".format(seconds))
#QtCore.pyqtSlot()
def on_myThread_finished(self):
print "Done"
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('myWindow')
main = myWindow()
main.show()
sys.exit(app.exec_())
Related
I am writing a GUI using pyqt5 (Python 3.6). I am trying to run another thread in parallel of the main GUI. I would like this child thread to terminate when I close the main application. In this example, the child thread is a simple counter. When I close the main GUI, the counter still keeps going. How can I get the thread to end when the GUI window is closed? In the real case I may have a thread that is running operations that takes a few minutes to execute. I am reluctant to use a flag within the thread to assess if it should end because it may take minutes for the thread to close after the GUI window has been closed. I would prefer the thread to end right away. Any suggestions?
Thank you.
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (QWidget, QApplication,QPushButton,
QVBoxLayout)
import time, threading, sys
class testScriptApp(QtWidgets.QWidget):
def __init__(self, parent=None):
# initialize th widget
QtWidgets.QWidget.__init__(self, parent)
# set the window title
self.setWindowTitle("Scripting")
# manage the layout
self.mainGrid = QVBoxLayout()
self.button = QPushButton('Start')
self.button.clicked.connect(self.on_click)
self.mainGrid.addWidget(self.button)
self.setLayout(self.mainGrid)
def on_click(self):
self.worker = threading.Thread(target=Worker)
self.worker.daemon = True
self.worker.start()
def Worker(count=1):
while count>0:
print(count)
time.sleep(2)
count+=1
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = testScriptApp()
myapp.show()
app.exec_()
I tried to use the QThread but this locks up the main GUI. I am not sure if I am implementing it correctly.
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (QWidget, QApplication,QPushButton,
QVBoxLayout)
from PyQt5.QtCore import QThread
import time, threading, sys
class testScriptApp(QtWidgets.QWidget):
def __init__(self, parent=None):
# initialize th widget
QtWidgets.QWidget.__init__(self, parent)
# set the window title
self.setWindowTitle("Scripting")
# manage the layout
self.mainGrid = QVBoxLayout()
self.button = QPushButton('Start')
self.button.clicked.connect(self.on_click)
self.mainGrid.addWidget(self.button)
self.setLayout(self.mainGrid)
def on_click(self):
self.worker = Worker()
self.worker.run()
def closeEvent(self,event):
print('Closing')
self.worker.terminate()
event.accept()
class Worker(QThread):
def __init__(self):
QThread.__init__(self)
def run(self):
count=1
while count>0:
print(count)
time.sleep(2)
count+=1
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = testScriptApp()
myapp.show()
app.exec_()
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (QWidget, QApplication,QPushButton,
QVBoxLayout)
from PyQt5.QtCore import QThread,QObject
import time, threading, sys
class testScriptApp(QtWidgets.QWidget):
def __init__(self, parent=None):
# initialize th widget
QtWidgets.QWidget.__init__(self, parent)
# set the window title
self.setWindowTitle("Scripting")
# manage the layout
self.mainGrid = QVBoxLayout()
self.button = QPushButton('Start')
self.button.clicked.connect(self.on_click)
self.mainGrid.addWidget(self.button)
self.setLayout(self.mainGrid)
def on_click(self):
self.my_thread = QThread()
self.worker = Worker()
self.worker.moveToThread(self.my_thread)
self.my_thread.started.connect(self.worker.run)
self.my_thread.start()
def closeEvent(self,event):
print('Closing')
class Worker(QObject):
def __init__(self):
super().__init__()
def run(self):
count=1
while count>0:
print(count)
time.sleep(2)
count+=1
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = testScriptApp()
myapp.show()
app.exec_()
hope self.my_thread.requestInterruption() won't qualify as flag, otherwise is not the sought answer :
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (QWidget, QApplication,QPushButton,
QVBoxLayout)
from PyQt5.QtCore import QThread,QObject
import time, threading, sys
class testScriptApp(QtWidgets.QWidget):
def __init__(self, parent=None):
# initialize th widget
QtWidgets.QWidget.__init__(self, parent)
# set the window title
self.setWindowTitle("Scripting")
# manage the layout
self.mainGrid = QVBoxLayout()
self.button = QPushButton('Start')
self.button.clicked.connect(self.on_click)
self.mainGrid.addWidget(self.button)
self.setLayout(self.mainGrid)
def on_click(self):
self.my_thread = QThread()
self.worker = Worker(self.my_thread)
self.worker.moveToThread(self.my_thread)
self.my_thread.started.connect(self.worker.run)
self.my_thread.start()
def closeEvent(self,event):
self.my_thread.requestInterruption()
print('Closing')
self.my_thread.quit()
self.my_thread.wait()
print('is thread running ?', self.my_thread.isRunning())
class Worker(QObject):
def __init__(self, thread):
super().__init__()
self.thread = thread
def run(self):
count=1
while count>0:
print(count)
time.sleep(2)
count+=1
if self.thread.isInterruptionRequested():
break
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = testScriptApp()
myapp.show()
app.exec_()
see PySide6.QtCore.QThread.isInterruptionRequested()
Using threading.thread like in your question, I used threading.Event() and I set it (= True) to stop your Worker loop, but once again I hope is not a flag:
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (QWidget, QApplication,QPushButton,
QVBoxLayout)
import time, threading, sys
class testScriptApp(QtWidgets.QWidget):
def __init__(self, parent=None):
# initialize th widget
QtWidgets.QWidget.__init__(self, parent)
# set the window title
self.setWindowTitle("Scripting")
# manage the layout
self.mainGrid = QVBoxLayout()
self.button = QPushButton('Start')
self.button.clicked.connect(self.on_click)
self.mainGrid.addWidget(self.button)
self.setLayout(self.mainGrid)
self.event = threading.Event()
def on_click(self):
self.worker = threading.Thread(target=Worker, args = (self.event,))
self.worker.daemon = True
self.worker.start()
def closeEvent(self, event):
if 'worker' in self.__dict__:
self.event.set() ## sets event: threading.Event() = True
self.worker.join() ## waits self.worker to complete ***
print('is worker alive, self.worker.is_alive() : ', self.worker.is_alive())
pass
def Worker(event, count=1 ):
print(event)
while count>0:
print(count)
time.sleep(2)
count+=1
if event.is_set():
break
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
myapp = testScriptApp()
myapp.show()
app.exec_()
try the code commenting and uncommentig out self.event.set() & self.worker.join() in
def closeEvent(self, event):
if 'worker' in self.__dict__:
self.event.set() ## sets event: threading.Event() = True
self.worker.join() ## waits self.worker to complete ***
print('is worker alive, self.worker.is_alive() : ', self.worker.is_alive())
pass
*** Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is called terminates –
I am trying to create a worker thread whose job is to monitor the status bit of a positioning platform.
To do this I connect a QTimer timeout signal to a function that queries the platform.
class expSignals(QtCore.QObject):
pause=QtCore.pyqtSignal()
class motorpositioner(QtCore.QObject):
def __init__(self):
QtCore.QThread.__init__(self)
self.timer = QtCore.QTimer()
self.timer.start(100)
self.timer.timeout.connect(self.do_it)
self.lock=QtCore.QMutex()
self.running=True
self.stat=0
def do_it(self):
with QtCore.QMutexLocker(self.lock):
#self.stat = self.motors.get_status()
print(self.stat)
time.sleep(5)
#QtCore.pyqtSlot()
def stop1(self):
self.timer.stop()
print('stop heard')
The GUI stuff looks like this:
class MyApp(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.thread=QtCore.QThread(self)
#worker
self.mot=motorpositioner()
# =============================================================================
# Putting buttons and GUI stuff in place
# =============================================================================
self.button=QtWidgets.QPushButton('Derp',self)
layout = QtWidgets.QHBoxLayout()
layout.addWidget(self.button)
self.setLayout(layout)
self.setGeometry( 300, 300, 350, 300 )
# =============================================================================
# Connecting signals
# =============================================================================
self.sig=expSignals()
self.sig2=expSignals()
self.button.clicked.connect(self.stop)
self.sig.pause.connect(self.mot.stop1)
self.sig2.pause.connect(self.thread.quit)
self.mot.moveToThread(self.thread)
self.thread.start()
def stop(self):
self.sig.pause.emit()
def closeEvent(self,event):
self.sig2.pause.emit()
event.accept()
However the way it is written now the GUI is unresponsive. However if I comment out self.timer.timeout.connect(self.do_it) and put do_it in a while(True) loop, the GUI isn't being blocked.
Why is the main thread being blocked when using QTimer?
I do not know what is expSignals() and I think it is not relevant, and neither is the button.
Your code has the following errors:
You are starting the timer before the thread starts, so the task will run on the GUI thread.
QTimer is not a child of motorpositioner so if motorpositioner moves to the new thread QTimer will not. For him to move he must be a son so you must pass him as a parent to self.
I do not know if it is a real error, but you are firing the QTimer every 100 ms but the task takes 5 seconds, although the QMutex helps to have no problems because it is blocked.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
import time
class motorpositioner(QtCore.QObject):
def __init__(self):
QtCore.QThread.__init__(self)
self.timer = QtCore.QTimer(self)
self.lock = QtCore.QMutex()
self.running = True
self.stat = 0
def start_process(self):
self.timer.timeout.connect(self.do_it)
self.timer.start(100)
def do_it(self):
with QtCore.QMutexLocker(self.lock):
#self.stat = self.motors.get_status()
print(self.stat)
time.sleep(5)
#QtCore.pyqtSlot()
def stop1(self):
self.timer.stop()
print('stop heard')
class MyApp(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.thread = QtCore.QThread(self)
self.mot = motorpositioner()
self.mot.moveToThread(self.thread)
self.thread.started.connect(self.mot.start_process)
self.thread.start()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = MyApp()
ex.show()
sys.exit(app.exec_())
I am totally stuck with this python qt threading tutorial. I have two issues.
1) The longRunning function never executes.
2) When exiting the app, I get QThread: Destroyed while thread is still running and a Python.exe has stopped working.
Any help? Thanks!!
#!/usr/bin/env python2
import sys, time
from PySide.QtGui import *
from PySide import QtCore
class SeperateThread(QtCore.QObject):
finished = QtCore.Signal()
def __init__(self, parent = None):
super(SeperateThread, self).__init__(parent)
self._isRunning = True
def longRunning(self):
end = time.time()+3
while self._isRunning == True:
sys.stdout.write('*')
sys.stdout.flush()
time.sleep(1)
now = time.time()
if now>=end:
self._isRunning=False
self.finished.emit()
def stop(self):
self._isRunning = False
class MainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self,parent)
centralwidget = QWidget(self)
startButton = QPushButton('Start long (3 seconds) operation',self)
label2 = QLabel('Long batch')
vbox = QVBoxLayout()
vbox.addWidget(startButton)
vbox.addWidget(label2)
self.setCentralWidget(centralwidget)
centralwidget.setLayout(vbox)
obj = SeperateThread()
objThread = QtCore.QThread()
obj.moveToThread(objThread)
objThread.started.connect(obj.longRunning)
def LongOperationStart():
label2.setText('app is running')
startButton.setEnabled(False)
objThread.start()
def LongOperationFinish():
startButton.setEnabled(True)
#GUI start button
startButton.clicked.connect(LongOperationStart)
#Once thread is finished.
objThread.finished.connect(LongOperationFinish)
obj.finished.connect(objThread.quit)
if __name__=='__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Oh ok, I found out what I was doing wrong:
SeperateThread is being garbage collected after the MainWindow constructor returns. Make obj a member of MainWindow so that it persists beyond the constructor.
Thanks!!
I am trying to emit a signal when a python thread finish running so when it is done, the emtited signal close the PYQT window that started the thread.
in the code see comments.
import sys
import threading
from PyQt4 import QtGui, QtCore
class MyThread(threading.Thread):
""" docstring for MyThread
"""
def __init__(self, job_done, settings):
super(MyThread, self).__init__()
self._Settings = settings
def run(self):
while not job_done.is_set():
if not processSetting(self._Settings):
raise Exception("Could not process settings")
else:
## Emit Signal
pass
class MyWindow(QtGui.QWidget):
"""docstring for MyWindow"""
def __init__(self, settings, parent=None):
super(MyWindow, self).__init__(parent)
self._Settings = settings
self._job_done = threading.Event()
self._myThread = MyThread(self._job_done, self._Settings)
## catch the signal to close this window.
def closeEvent(self, event):
if self._myThread.isAlive():
reply=QtGui.QMessageBox.question(self, "Are you sure to quit?","Settings are getting applied !!!",QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)
if reply==QtGui.QMessageBox.Yes:
event.accept()
else:
event.ignore()
def processSettings():
print "processSettings() Called"
return True
def main():
app = QtGui.QApplication(sys.argv)
main = MyWindow()
main.show()
sys.exit(app.exec_())
in the above code i want to signal when processSttingts returns True
and then MyWindow should close.
EDIT here is what I tried to do.
So what I am heading towards is to emit a signal if the processSettings returns True and close the QMainWindow MyWindow.
import sys
import threading
from PyQt4 import QtGui, QtCore
def processSettings():
print "processSettings() Called"
return True
class MyThread(threading.Thread):
""" docstring for MyThread
"""
def __init__(self, settings):
super(MyThread, self).__init__()
self._Settings = settings
self.signal = QtCore.SIGNAL("signal")
self._job_done = threading.Event()
def run(self):
# while not job_done.is_set():
print "in thread"
if not processSettings():
raise Exception("Could not process settings")
else:
QtCore.emit(self.signal, "hi from thread")
class MyWindow(QtGui.QMainWindow):
"""docstring for MyWindow"""
def __init__(self, settings, parent=None):
super(MyWindow, self).__init__(parent)
self._Settings = settings
self._myThread = MyThread(self._Settings)
self._myThread.daemon = False
self._myThread.start()
self.connect(self._myThread, self._myThread.signal, self.testfunc)
def closeEvent(self, event):
if self._myThread.isAlive():
reply=QtGui.QMessageBox.question(self, "Are you sure to quit?","Settings are getting applied !!!",QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)
if reply==QtGui.QMessageBox.Yes:
event.accept()
else:
event.ignore()
def testfunc(self, sigstr):
""" Purpose of this function is to close this window"""
print sigstr
self.close()
def main():
app = QtGui.QApplication(sys.argv)
settings = {'test': True}
wind = MyWindow(settings)
wind.show()
sys.exit(app.exec_())
if __name__ == '__main__':
sys.exit(main())
You need to ensure that the solution is thread-safe, and directly connecting signals emitted from a python thread to a slot in QT thread is not thread safe. The SafeConnector class proposed by mguijarr in his answer to "Emit signal in standard python thread" may be useful. I successfully use a modified version of his solution that uses a pipe rather than a socket:
class SafeConnector(object):
"""Share between Python thread and a Qt thread.
Qt thread calls :meth:`connect` and the python thread calls :meth:`emit`.
The slot corresponding to the emitted signal will be called in Qt's
thread.
"""
def __init__(self):
self._fh_read, self._fh_write = os.pipe()
self._queue = Queue.Queue()
self._qt_object = QtCore.QObject()
self._notifier = QtCore.QSocketNotifier(self._fh_read,
QtCore.QSocketNotifier.Read)
self._notifier.activated.connect(self._recv)
def close(self):
del self._qt_object
self._qt_object = None
os.close(self._fh_read)
os.close(self._fh_write)
self._fh_read, self._fh_write = None, None
def connect(self, signal, receiver):
"""Connect the signal to the specified receiver slot.
:param signal: The signal to connected.
:param receiver: The receiver slot for the signal.
"""
QtCore.QObject.connect(self._qt_object, signal, receiver)
def emit(self, signal, *args):
"""Emit a Qt signal from a python thread.
All remaning args are passed to the signal.
:param signal: The Qt signal to emit.
"""
self._queue.put((signal, args))
os.write(self._fh_write, '!')
def _recv(self):
"""Receive the signal from the Queue in Qt's main thread."""
os.read(self._fh_read, 1)
signal, args = self._queue.get()
self._qt_object.emit(signal, *args)
The example from mguijarr's post is valid using either implementation.
Here is an example of the solution I proposed in the comments:
from PyQt4 import QtGui, QtCore
import threading
import time
class MyThread(threading.Thread):
def __init__(self, *args):
threading.Thread.__init__(self, *args)
self.job_done = threading.Event()
self.qt_object = QtCore.QObject()
def end_job(self):
self.job_done.set()
def run(self):
while not self.job_done.is_set():
time.sleep(1)
QtCore.QObject.emit(self.qt_object, QtCore.SIGNAL("job_done"))
th = MyThread()
th.start()
app = QtGui.QApplication([])
w = QtGui.QWidget()
btn = QtGui.QPushButton('click me to exit', w)
QtGui.QVBoxLayout(w)
w.layout().addWidget(btn)
def btn_clicked():
th.end_job()
QtCore.QObject.connect(btn, QtCore.SIGNAL("clicked()"), btn_clicked)
QtCore.QObject.connect(th.qt_object, QtCore.SIGNAL("job_done"), w.close)
w.show()
app.exec_()
I want to ask how is it possible to refresh QLCDNumbers after I have started some measures.
I created an GUI thread to connect the signals to QLCDNumbers like that:
class BtDialog(QtGui.QDialog, Dlg):
def __init__(self):
QtGui.QDialog.__init__(self)
self.setupUi(self)
self.thread = WorkerThread()
#Configure slots
self.connect(self.startButton, QtCore.SIGNAL("clicked()"), self.onStart)
self.connect(self.stopButton, QtCore.SIGNAL("clicked()"), self.onStop)
#QLCDNumber Slot
self.connect(self.thread, self.thread.voltage, self.lcdVoltage.display)
def onStart(self):
self.thread.start()
def onStop(self):
self.emit(self.thread.voltage, 0) #Trying to refresh
abort()
Here I connect two buttons, one for starting the worker thread and the other to stop the process. When I stop the process I want to refresh the QLCDNumber by displaying '0' but it doesn't work.
In worker thread i initialize the signal like that:
def __init__(self, parent = None):
QtCore.QThread.__init__(self, parent)
self.voltage = QtCore.SIGNAL("voltage")
And when the process runs I emit the signal with
self.emit(self.voltage, volt_act)
after measuring. That works so far. But after stopping when I want to start the worker process again the signal doesn't emit to QLCDNumber again. For that I have to restart the GUI. How can I fix the two problems of mine for that I want to refresh QLCDNumber and over that after stopping and refreshing emitting the signal again?
Can't tell where the issue is from the code you posted, but this should help you modify it, also checkout the docs for new-style signal/slot connections and further reference (modal dialogs, timers, etc):
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import time
from PyQt4 import QtGui, QtCore
class MyThread(QtCore.QThread):
countChange = QtCore.pyqtSignal(int)
countReset = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
super(MyThread, self).__init__(parent)
self.stopped = QtCore.QEvent(QtCore.QEvent.User)
def start(self):
self.stopped.setAccepted(False)
self.count = 0
super(MyThread, self).start()
def run(self):
while not self.stopped.isAccepted():
self.count += 1
self.countChange.emit(self.count)
time.sleep(1)
self.countReset.emit(0)
def stop(self):
self.stopped.setAccepted(True)
class MyWindow(QtGui.QDialog):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.lcdNumber = QtGui.QLCDNumber(self)
self.pushButtonStart = QtGui.QPushButton(self)
self.pushButtonStart.setText("Start")
self.pushButtonStart.clicked.connect(self.on_pushButtonStart_clicked)
self.pushButtonStop = QtGui.QPushButton(self)
self.pushButtonStop.setText("Stop")
self.pushButtonStop.clicked.connect(self.on_pushButtonStop_clicked)
self.pushButtonDone = QtGui.QPushButton(self)
self.pushButtonDone.setText("Done")
self.pushButtonDone.clicked.connect(self.on_pushButtonDone_clicked)
self.layoutHorizontal = QtGui.QHBoxLayout(self)
self.layoutHorizontal.addWidget(self.lcdNumber)
self.layoutHorizontal.addWidget(self.pushButtonStart)
self.layoutHorizontal.addWidget(self.pushButtonStop)
self.layoutHorizontal.addWidget(self.pushButtonDone)
self.thread = MyThread(self)
self.thread.countChange.connect(self.lcdNumber.display)
self.thread.countReset.connect(self.lcdNumber.display)
#QtCore.pyqtSlot()
def on_pushButtonStart_clicked(self):
self.thread.start()
#QtCore.pyqtSlot()
def on_pushButtonStop_clicked(self):
self.thread.stop()
#QtCore.pyqtSlot()
def on_pushButtonDone_clicked(self):
sys.exit()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.exec_()
sys.exit(app.exec_())