Prozess alle X Sekunden ausführen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

Hallo,

ich habe einen Prozess, der eine Ansicht aktualisieren soll. Der Prozess soll auf Knopfdruck gestartet werden, die Aktion ausführen und sich dann für 30 Sekunden schlafen legen und danach die Aktion wieder ausführen. Der Prozess selber darf nicht doppelt gestartet werden.

Wie mache ich das am besten.
Ich habe das ganze mit threading versucht. Bin aber irgendwie nicht auf einen Grünen Zweig gekommen. Also die UpdateFunktion an sich ist kein großer Akt.


so in der Richtung habe ich probiert. Das hat aber zur Folge, dass der Thread mehrfach gestartet werden kann und ich mit dem Ergebnis nicht wirklich zufrieden bin.

Code: Alles auswählen

def update():
  while 1:
    logging.debug('doing update')
    time.sleep(30)

a = threading.Thread(target=update, name='updateThread')
a.start()

Was mir gerade noch eingefallen ist.
Wäre es sinnvoll 2 Prozesse zu haben, welche sich gegenseitig aufrufen, bzw. in dem eigentlichen updateProzess einen Timer aufzurufen, welcher den UpdateProzess erneut startet?

Code: Alles auswählen

def update_():
    logging.info('doing update')
    logging.debug('calling waiter')
    threading.Timer(5.0,update_).start()
    logging.debug('update finished')
    logging.debug('Anzahl Threads: %d' % threading.activeCount())

update_()

Code: Alles auswählen

[INFO] (MainThread) doing update
[DEBUG] (MainThread) calling waiter
[INFO] (MainThread) update finished
[DEBUG] (MainThread) Anzahl Threads: 3
[INFO] (Thread-1  ) doing update
[DEBUG] (Thread-1  ) calling waiter
[INFO] (Thread-1  ) update finished
[DEBUG] (Thread-1  ) Anzahl Threads: 4
[INFO] (Thread-2  ) doing update
[DEBUG] (Thread-2  ) calling waiter
[INFO] (Thread-2  ) update finished
[DEBUG] (Thread-2  ) Anzahl Threads: 4
[INFO] (Thread-3  ) doing update
[DEBUG] (Thread-3  ) calling waiter
[INFO] (Thread-3  ) update finished
[DEBUG] (Thread-3  ) Anzahl Threads: 4
Bedenken, Anregungen etc sind gern willkommen.
Gruß,
Steffen
BlackJack

@knumskull: Was bringt Dir das Zweite Beispiel gegenüber dem ersten? Also statt einem Thread für jedes Update einen neuen zu starten?

Das verhindern, dass mehrere dieser Threads gleichzeitig laufen lässt sich doch einfach abfangen in dem man bei dem Button vermerkt, ob man das ganze schon gestartet hat. Vielleicht auch den Button deaktivieren, damit der Benutzer den gar nicht noch einmal drücken kann.

Womit wir bei einem viel grösseren Problem währen: Das klingt nach GUI und auf GUI-Elemente aus einem anderen Thread zugreifen, als dem in dem die GUI-Hauptschleife läuft, ist in den meisten GUI-Toolkits verboten oder erfordert zusätzliche Massnahmen. Auf der anderen Seite bieten die meisten GUI-Toolkits aber Möglichkeiten um Funktionen zu registrieren, die erst nach einer gewissen Zeit oder auch in regelmässigen Abständen aufgerufen werden. Das sollte man für diesen Fall IMHO Threads vorziehen.
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

@BlackJack: Was mir der zweite bringt, weiß ich nicht, es war eine Idee, wie ich das Problem umsetzen kann. Mehr nicht. deswegen Frage ich, bevor ich sinnlose Sachen implementieren.

Ich habe mich da vielleicht schlecht ausgedrückt, bzw. was anderes geschrieben, als ich gemeint habe.
Was ich eigentlich will, ist dass bei einer Aktion der UpdateProzess gestartet wird und dieser dann so lange läuft, bis das Fenster geschlossen ist.

zu der GUI-Geschicht. Es handelt sich um ein QTreeWidget auf einem QMainWindow, in welchem der Inhalt alle 30 Sekunden aktualisiert werden soll. Ich habe hier im Forum schon ein paar Sachen gelesen, aber wie ich das umsetzen soll, weiß ich nicht.

Kannst du mir ein paar Schlagworte geben, nach denen ich suchen kann?
Kennst du für pyQt die entsprechenden Funktionen, die es mir ermöglichen Sachen verspätet oder in regelmäßigen Abständen zu starten?

Danke im Voraus
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

@lunar: :-) ... Habe ich in der zwischenzeit auch gelesen.

Also an Stelle von Thread, einfach QThread einsetzen. Das sollte das erste Problem beheben, denke ich mal. Bleibt weiterhin die Frage, wie ich meinen Prozess/Thread "baue"

Code: Alles auswählen

def update():
  while 1:
    logging.debug('doing update')
    time.sleep(30)

a = QThread(target=update, name='updateThread')
a.start()
Ich will es so haben, dass der Thread die ganze Zeit aktiv ist, während das Fenster aktiv ist. Überprüfen kann ich das ganze ja mittels

Code: Alles auswählen

self.mainwindow.isVisible()
Wo wäre die Stelle zum Starten des Threads am besten? In der __init__-Methode ist das Objekt ja noch nicht sichtbar. Sinnvoll die show-Methode anzupassen oder gibt es Alternativen?
lunar

@knumskull: Jetzt lese meinen Beitrag nochmal, und sag mir bitte, wie Du aus meinem Beitrag irgendeinem Zusammenhang mit "QThread" herstellst?!
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

@lunar: das Frage ich mich auch gerade :) Das passiert wohl, wenn man mit was anfängt zu schreiben und dann zwischenzeitlich was anderes macht. Dann war das eher die Antwort auf das Problem von BlackJack, auf welches er hingewiesen hat.

ist es folgendes was du meinst?

Code: Alles auswählen

from PyQt4.QtCore import *

def update():
    print('doing update')


timer = QTimer()
QObject.connect(timer, SIGNAL("timeout()"), update)
timer.start(200)
allerdings will es noch nicht so richtig klappen.

Die passende Stelle in der Qt-Doku lautet ja ungefähr folgendermaßen

Code: Alles auswählen

QTimer *timer = new QTimer(this);
     connect(timer, SIGNAL(timeout()), this, SLOT(update()));
     timer->start(1000);
Ich tue mich aber gerade etwas schwer, den c-Code in python zu transferieren.
lunar

Grob ist das korrekt. "QTimer" benötigt allerdings eine laufende Ereignisschleife, vor "QApplication.exec_()" wird also kein Zeitgeber ausgelöst. Wenn es aus anderen Gründen „nicht so richtig klappen will“, dann ist der Zeitpunkt gekommen, eine präzise Fehlerbeschreibung zu geben :)
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

@lunar: dann werde ich das mit der App-schleife nochmal testen. Danke erst einmal für die Tipps. Ich denke ich melde mich noch einmal. :-)
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

Mit eine APP-Schleife drumherum klappt es mittlerweile hervorragend.

Danke
Antworten