Signals von überall aus erreichbar machen
-
- User
- Beiträge: 55
- Registriert: Mittwoch 11. Juli 2018, 11:11
Ah, das ist wirklich cool! Und so wie ich das sehe, wird dann "send()" auch im gleichen Thread ausgeführt wie der Worker und damit queued?!
-
- User
- Beiträge: 55
- Registriert: Mittwoch 11. Juli 2018, 11:11
Kann man eigentlich problemlos Funktionen im Worker aufrufen? (abgesehen von worker.work())
Ich würde gerne etwas in der Richtung umsetzten:
Ist jetzt nicht schön gelöst, ich weiß, es geht nur ums Prinzip: Also eine Möglichkeit den Worker zu pausieren. Theoretisch würde es auch gehen, ihn zu schließen und neu zu starten, aber ich dachte pausieren ist vielleicht etwas leichter.
Ich würde gerne etwas in der Richtung umsetzten:
Code: Alles auswählen
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from time import sleep
from PySide2.QtCore import QObject, Signal, QThread
from PySide2.QtWidgets import (QApplication, QWidget, QLabel,
QPushButton, QVBoxLayout)
class Worker(QObject):
progress = Signal(str)
def __init__(self):
QObject.__init__(self)
self._pause = False
self.is_running = True
self.count = 0
def work(self):
while self.is_running:
if not self._pause:
self.progress.emit(str(self.count))
self.count += 1
sleep(0.2)
def pause(self):
self._pause = True
def start(self):
self._pause = False
def quit(self):
self.is_running = False
def main():
app = QApplication(sys.argv)
worker_thread = QThread()
worker = Worker()
worker_thread.started.connect(worker.work)
worker.moveToThread(worker_thread)
def run_worker():
if button.text() == 'Start':
worker.start()
if not worker_thread.isRunning():
worker_thread.start()
button.setText("Stop")
else:
button.setText("Start")
worker.pause()
def stop_worker():
worker.quit()
worker_thread.quit()
worker_thread.wait()
app.aboutToQuit.connect(stop_worker)
w = QWidget()
w.setWindowTitle('Signal Sender')
layout = QVBoxLayout(w)
label = QLabel(w)
button = QPushButton(w)
button.setText("Start")
button.clicked.connect(run_worker)
layout.addWidget(label)
layout.addWidget(button)
def update_label(text):
label.setText(text)
worker.progress.connect(update_label)
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Ich verstehe nicht, was deine Frage mit dem Code zu tun hat.
Wie dem auch sei: ja man kann problemlos Funktionen aus dem Worker aufrufen.
Und statt mit so einer Frickelei löst man so etwas wie schon mal besprochen mit einer Queue von Arbeitsaufträgen. Dann wird der Thread wirklich schlafen gelegt, und dann bei bedarf wieder aufgeweckt.
Wie dem auch sei: ja man kann problemlos Funktionen aus dem Worker aufrufen.
Und statt mit so einer Frickelei löst man so etwas wie schon mal besprochen mit einer Queue von Arbeitsaufträgen. Dann wird der Thread wirklich schlafen gelegt, und dann bei bedarf wieder aufgeweckt.
Und noch ein Nachtrag: in dem von mir mal verlinkten anderen Beitrag hier verargumentieren wir, dass es nicht nötig ist, Threads zu startet und zu stoppen. Starte einfach einen zu Beginn der Anwendung, und lass ihn Aufträge abarbeiten. Und ein Auftrag kann dann “beende dich” sein, worauf dann natürlich mit join gewartet werden muss.
-
- User
- Beiträge: 55
- Registriert: Mittwoch 11. Juli 2018, 11:11
Die Queue verwende ich auch in meinem original Script, aber da war es bis dato so, dass die Auftragsschlange irgendwann mal fertig war. Allerdings soll es die Möglichkeit geben, die Auftragsliste zu reseten, aufzufüllen und wieder neu zu starten.