Skip to content

Instantly share code, notes, and snippets.

@ydm
Last active August 29, 2015 14:05
Show Gist options
  • Save ydm/9a42a85431134bd4b7eb to your computer and use it in GitHub Desktop.
Save ydm/9a42a85431134bd4b7eb to your computer and use it in GitHub Desktop.
PyQt4 + UI Looper
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import Queue
import functools
import itertools
import sys
import threading
import time
from PyQt4 import QtCore
from PyQt4 import QtGui
class Looper(object):
def __init__(self):
self.main_id = id(threading.current_thread())
self.tasks = Queue.Queue()
def process(self):
try:
task = self.tasks.get_nowait()
except Queue.Empty:
pass
else:
f, args, kw = task
f(*args, **kw)
def enqueue_task(self, f, args=None, kw=None):
task = f, args or [], kw or {}
self.tasks.put(task)
def run_in_ui(self, func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
if id(threading.current_thread()) == self.main_id:
return func(*args, **kwargs)
else:
return self.enqueue_task(func, args, kwargs)
return wrapper
class Top(QtGui.QMainWindow):
looper = Looper()
def __init__(self, *args, **kwargs):
super(Top, self).__init__(*args, **kwargs)
# Ui
self.text = None
self.setup_ui()
# Timer
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.looper.process)
self.timer.start(50)
def setup_ui(self):
self.text = QtGui.QLineEdit(self)
self.text.show()
@looper.run_in_ui
def set_text(self, text):
self.text.setText(text)
class Changer(object):
run = True
def change(self, w):
for x in itertools.count():
if not self.run:
break
w.set_text('{}s'.format(x))
time.sleep(1)
def stop(self):
self.run = False
def main():
app = QtGui.QApplication(sys.argv)
w = Top()
w.show()
changer = Changer()
app.lastWindowClosed.connect(changer.stop)
t = threading.Thread(target=changer.change, args=(w,))
t.start()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment