Skip to content

Instantly share code, notes, and snippets.

@justinfx
Created December 27, 2014 03:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinfx/a470dc7ff89538620968 to your computer and use it in GitHub Desktop.
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)
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