Created
December 27, 2014 03:16
-
-
Save justinfx/a470dc7ff89538620968 to your computer and use it in GitHub Desktop.
Example of using worker QThreads to process data before loading web results. (pyside, qt)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from PySide import QtCore, QtGui, QtWebKit | |
from threading import current_thread | |
class MainWindow(QtGui.QMainWindow): | |
def __init__(self): | |
super(MainWindow, self).__init__() | |
container = QtGui.QWidget(self) | |
self._tab = QtGui.QTabWidget(container) | |
self._button = QtGui.QPushButton("New", container) | |
layout = QtGui.QVBoxLayout(container) | |
layout.setContentsMargins(4,4,4,4) | |
layout.addWidget(self._tab) | |
layout.addWidget(self._button) | |
self.setCentralWidget(container) | |
self._button.clicked.connect(self.newPage) | |
def newPage(self): | |
page = BrowserPage(self._tab) | |
self._tab.addTab(page, "Page %d" % self._tab.count()) | |
page.start() | |
class BrowserPage(QtGui.QFrame): | |
""" | |
A web page view that will do long-running work in a thread, | |
and then load the results when ready. | |
""" | |
loadStarted = QtCore.Signal() | |
loadFinished = QtCore.Signal() | |
def __init__(self, parent=None): | |
super(BrowserPage, self).__init__(parent) | |
self.__thread = None | |
self.__loader = None | |
self.__view = QtWebKit.QWebView(self) | |
self.__stat = QtGui.QStatusBar(self) | |
self.__stat.setSizeGripEnabled(False) | |
self.__stat.setFixedHeight(22) | |
layout = QtGui.QVBoxLayout(self) | |
layout.setContentsMargins(0,0,0,0) | |
layout.setSpacing(0) | |
layout.addWidget(self.__view) | |
layout.addWidget(self.__stat) | |
def start(self): | |
if self.__thread is not None: | |
return | |
thread = QtCore.QThread() | |
loader = PageLoader() | |
loader.moveToThread(thread) | |
thread.started.connect(loader.load) | |
thread.finished.connect(self.__finished) | |
loader.progress.connect(self.__updateProgress) | |
loader.finished.connect(self.__view.load) | |
loader.finished.connect(thread.quit) | |
self.__thread = thread | |
self.__loader = loader | |
self.loadStarted.emit() | |
self.__stat.showMessage("Starting to load...") | |
thread.start() | |
def __updateProgress(self, prog): | |
self.__stat.showMessage("Loaded {:.1%}".format(prog)) | |
def __finished(self): | |
self.__stat.clearMessage() | |
self.loadFinished.emit() | |
self.__thread.deleteLater() | |
self.__loader.deleteLater() | |
self.__thread = None | |
self.__loader = None | |
class PageLoader(QtCore.QObject): | |
""" | |
Provides the logic for processing web content concurrently, | |
and emitting results when ready. | |
""" | |
progress = QtCore.Signal(float) | |
finished = QtCore.Signal(QtCore.QUrl) | |
def load(self): | |
tid = current_thread().ident | |
num = 5 | |
for i in xrange(1, num+1): | |
print "(Thread: %d) Loading %d/%d ..." % (tid, i, num) | |
QtCore.QThread.sleep(1) | |
self.progress.emit(i/float(num)) | |
url = QtCore.QUrl("http://www.google.com") | |
self.finished.emit(url) | |
if __name__ == "__main__": | |
app = QtGui.QApplication([]) | |
w = MainWindow() | |
w.resize(1024, 768) | |
w.show() | |
w.raise_() | |
app.exec_() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment