im Thema Verständnisfrage: Wem übergebe ich die Argumente, der Klasse oder der Methode? haben __blackjack__ und __deets__ mich darauf aufmerksam gemacht, dass man Threads einmalig erstellt und im Laufe des Programmlaufes dem Thread mit Aufträge bestückt. Daraufhin habe ich eine Art Benchmark erstellt. Hierbei geht es um zwei Varianten vom Umgang mit dem Thread. Diese werde ich nachfolgend erklären, und anschließend präsentiere ich euch den dazugehörigen Quelltext. Eine weitere Anmerkung: Die nachfolgenden Quelltexte sind ausführbar.
In der ersten Variante wird jedesmal, wenn man auf den QPushButton namens "Start" klickt, ein Thread mit seinem Overhead erstellt. Das heißt, jeder Klick ein neuer Trhead. In der Counter()-Klasse wird durch die range()-Funktion simuliert, dass 10.000 Daten in das QTreeWidget() populiert werden. Die Zeit bei 10.000 Daten beträgt bei mir rund Duration: 0:00:10.353000.
Code: Alles auswählen
import sys
import time
from datetime import datetime
from PyQt4.QtCore import QTimer, QObject, pyqtSignal, \
QThread, Qt
from PyQt4.QtGui import QDialog, QLabel, QPushButton, \
QApplication, QVBoxLayout, QTreeWidget, QTreeWidgetItem
def output(text):
print "Output:", text
class Counter(QObject):
notify_progress = pyqtSignal(str)
notify_item = pyqtSignal(object)
finish_progress = pyqtSignal()
fire_label = pyqtSignal(int)
def __init__(self, parent=None):
QObject.__init__(self, parent)
def init_object(self):
# start to stopp the time
self.start_time = datetime.now()
self.element = self.my_gen()
self.timer = QTimer()
# assoziiert increment() mit TIMEOUT Ereignis
self.timer.setSingleShot(False)
self.timer.setInterval(1)
self.timer.timeout.connect(self.increment)
self.timer.start()
def my_gen(self):
count = 0
for name in xrange(10000):
count += 1
self.fire_label.emit(count)
yield name
def increment(self):
try:
self.notify_item.emit(next(self.element))
except StopIteration:
self.notify_progress.emit('Break the loop')
self.finish_progress.emit()
self.timer.stop()
# end with to stopp the time
self.end_time = datetime.now()
# Show how much time has been elapsed.
print('Duration: {}'.format(self.end_time - self.start_time))
def stop(self):
self.notify_progress.emit('Stop the loop')
self.timer.stop()
class MyCustomDialog(QDialog):
finish = pyqtSignal()
def __init__(self, parent=None):
QDialog.__init__(self, parent)
layout = QVBoxLayout(self)
self.tree = QTreeWidget(self)
self.label = QLabel(self)
self.pushButton_start = QPushButton("Start thread and populate", self)
self.pushButton_stopp = QPushButton("Stopp", self)
self.pushButton_close = QPushButton("Close", self)
layout.addWidget(self.label)
layout.addWidget(self.tree)
layout.addWidget(self.pushButton_start)
layout.addWidget(self.pushButton_stopp)
layout.addWidget(self.pushButton_close)
self.pushButton_start.clicked.connect(self.on_start)
self.pushButton_stopp.clicked.connect(self.on_finish)
self.pushButton_close.clicked.connect(self.close)
def fill_tree_widget(self, i):
parent = QTreeWidgetItem(self.tree)
self.tree.addTopLevelItem(parent)
parent.setText(0, unicode(i))
parent.setCheckState(0, Qt.Unchecked)
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
def on_label(self, i):
self.label.setText("Result: {}".format(i))
def on_start(self):
self.tree.clear()
self.label.clear()
task_thread = QThread(self)
task_thread.work = Counter()
task_thread.work.moveToThread(task_thread)
task_thread.work.fire_label.connect(self.on_label)
task_thread.work.notify_progress.connect(output)
task_thread.work.notify_item.connect(self.fill_tree_widget)
task_thread.work.finish_progress.connect(task_thread.quit)
self.finish.connect(task_thread.work.stop)
task_thread.started.connect(task_thread.work.init_object)
task_thread.finished.connect(task_thread.deleteLater)
task_thread.start()
def on_finish(self):
self.finish.emit()
def main():
app = QApplication(sys.argv)
window = MyCustomDialog()
window.resize(600, 400)
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Code: Alles auswählen
import sys
import time
from datetime import datetime
from PyQt4.QtCore import QTimer, QObject, pyqtSignal, \
QThread, Qt
from PyQt4.QtGui import QDialog, QLabel, QPushButton, \
QApplication, QVBoxLayout, QTreeWidget, QTreeWidgetItem
def output(text):
print "Output:", text
class Counter(QObject):
notify_progress = pyqtSignal(str)
notify_item = pyqtSignal(object)
fire_label = pyqtSignal(int)
def __init__(self, parent=None):
QObject.__init__(self, parent)
def init_object(self):
# start to stopp the time
self.start_time = datetime.now()
self.element = self.my_gen()
self.timer = QTimer()
# assoziiert increment() mit TIMEOUT Ereignis
self.timer.setSingleShot(False)
self.timer.setInterval(1)
self.timer.timeout.connect(self.increment)
self.timer.start()
def my_gen(self):
count = 0
for name in xrange(10000):
count += 1
self.fire_label.emit(count)
yield name
def increment(self):
try:
self.notify_item.emit(next(self.element))
except StopIteration:
self.notify_progress.emit('Break the loop')
self.timer.stop()
# end with to stopp the time
self.end_time = datetime.now()
# Show how much time has been elapsed.
print('Duration: {}'.format(self.end_time - self.start_time))
def stop(self):
self.notify_progress.emit('Stop the loop')
self.timer.stop()
class MyCustomDialog(QDialog):
finish_signal = pyqtSignal()
def __init__(self, parent=None):
QDialog.__init__(self, parent)
layout = QVBoxLayout(self)
self.tree = QTreeWidget(self)
self.label = QLabel(self)
self.pushButton_start = QPushButton("Start thread only", self)
self.pushButton_populate = QPushButton("Populate", self)
self.pushButton_stopp = QPushButton("Stopp", self)
self.pushButton_close = QPushButton("Close", self)
layout.addWidget(self.label)
layout.addWidget(self.tree)
layout.addWidget(self.pushButton_start)
layout.addWidget(self.pushButton_populate)
layout.addWidget(self.pushButton_stopp)
layout.addWidget(self.pushButton_close)
self.pushButton_start.clicked.connect(self.on_start_thread)
self.pushButton_populate.clicked.connect(self.on_start_populate_tree_widget)
self.pushButton_stopp.clicked.connect(self.finish_signal)
self.pushButton_close.clicked.connect(self.close)
def fill_tree_widget(self, i):
parent = QTreeWidgetItem(self.tree)
self.tree.addTopLevelItem(parent)
parent.setText(0, unicode(i))
parent.setCheckState(0, Qt.Unchecked)
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
def on_label(self, i):
self.label.setText("Result: {}".format(i))
def on_start_populate_tree_widget(self):
self.task_thread.work.init_object()
def on_start_thread(self):
self.task_thread = QThread()
self.task_thread.work = Counter(self)
self.task_thread.work.moveToThread(self.task_thread)
self.task_thread.work.fire_label.connect(self.on_label)
self.task_thread.work.notify_progress.connect(output)
self.task_thread.work.notify_item.connect(self.fill_tree_widget)
self.finish_signal.connect(self.task_thread.work.stop)
self.task_thread.finished.connect(self.task_thread.deleteLater)
self.task_thread.start()
def on_finish(self):
self.finish_signal.emit()
def main():
app = QApplication(sys.argv)
window = MyCustomDialog()
window.resize(600, 400)
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()