Seite 1 von 1
Nebenläufigkeit von GUI und Messgerätkalibrierung realisiere
Verfasst: Mittwoch 12. Februar 2014, 14:06
von dominik123
Hallo,
ich möchte mit Hilfe eines Pythonscripts mit visa Messgeräte ansteuern.
Um die Übersichtlichkeit zu verbessern möchte ich außerdem mit Hilfe von TKinter eine GUI programmieren.
Was wäre die beste Methode, um zu verhindern, dass das Interface "einfriert", sobald bei der Messgerätkalibrierung Wartezeiten entstehen.
Vielen Dank für eure Hilfe!
Gruß,
Dominik
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Mittwoch 12. Februar 2014, 14:28
von BlackJack
@dominik123: Du könntest die Kalibrierung in einem eigenen Thread (`threading`-Modul) laufen lassen. Wichtig ist, dass man nur vom Hauptthread aus Veränderungen an der GUI vornehmen darf. Falls der Arbeitsthread etwas in der GUI verändern soll, dann verwendet man üblicherweise `Queue.Queue`-Objekte um zwischen den beiden Threads zu kommunizieren und fragt im Hauptthread mittels `after()`-Methode regelmässig ob neue Daten in der Queue vorliegen.
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Freitag 14. Februar 2014, 09:42
von dominik123
Vielen Dank für die Antwort!
Zur Kalibrierung nutze ich momentan ein eigenes Script, das sehr umfangreich ist. Kann ich tatsächlich das gesamte Script als Thread aufrufen? Muss die Kalibrierung im gleichen Script ablaufen, wie die Erstellung des GUI?
Gruß,
Dominik
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Freitag 14. Februar 2014, 12:57
von BlackJack
@dominik123: Du kannst streng genommen nicht das Skript als Thread aufrufen aber Du kannst einen Thread starten in dem das Skript dann aufgerufen wird. Wenn es tatsächlich als eigener Prozess laufen soll gibt es dafür das `subprocess`-Modul. Ansonsten würde ich versuchen das Skript so zu schreiben das man es auch als Modul importieren kann und darin dann die entsprechende Funktion(en) aufrufen kann.
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Dienstag 18. Februar 2014, 09:18
von dominik123
Ich habe versucht, dass Kalibierungsscript mithilfe der import- Funktion in das GUI zu importieren. Wenn ich nun allerdings mein GUI starten möchte, so öffnet sich nur die Kalibrierung und sobald diese fertig ist öffnet sich das GUI. Worauf muss ich achten, wenn ich das Script als Modul importieren möchte?
Wie kann ich denn das ganze Script mithilfe eines Threads aufrufen?
Vielen Dank!
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Dienstag 18. Februar 2014, 09:30
von BlackJack
@dominik123: Du musst das Modul so schreiben das man es importieren kann ohne das es als Programm los läuft. Dafür wertet man in einem Modul `__name__` aus, was an den Modulnamen gebunden ist, ausser wenn man ein Modul direkt ausführt, dann ist es an den Wert '__main__' gebunden. Das Idiom sieht so aus:
Und in der `main()`-Funktion steht dann das Hauptprogramm.
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Dienstag 18. Februar 2014, 14:11
von dominik123
Vielen Dank!
Habe die Kalibrierung jetzt so umgeschrieben, dass ich sie als Modul importieren kann, ohne dass sie direkt los läuft.
Wenn ich nun jedoch (mittels Button) eine Funktion aus dem "Kalibrierungsmodul" aufrufe, friert mein GUI solange ein, bis diese Funktion vollständig abgearbeitet wurde. Hier kommt nun die eigentliche Nebenläufigkeit ins Spiel und diese bereitet mir immer noch Probleme!
Wie könnte ich eine Funktion wie z.B. "calibration.start_measurement()" in einen Thread auslagern, sodass mein GUI nicht mehr einfriert?
Mit dem Befehl thread.start_new_thread() komme ich momentan leider nicht weiter...
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Dienstag 18. Februar 2014, 14:32
von BlackJack
@dominik123: Das `thread`-Modul sollte man sowieso nicht mehr verwenden, deshalb hatte ich ja auf das `threading`-Modul verwiesen.
So ganz allgemein ohne mehr zu wissen kann man nur das hier sagen:
Code: Alles auswählen
thread = Thread(target=calibration.start_measurement)
thread.start()
Dann läuft die Funktion nebenläufig.
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Donnerstag 20. Februar 2014, 11:55
von dominik123
Hallo,
um eine Progressbar zu installieren habe ich folgende Funktion:
Code: Alles auswählen
def progress():
progressbar = ttk.Progressbar(orient=HORIZONTAL, length=140, mode='indeterminate', maximum=10)
progressbar.grid(row=7, column=5, sticky=W)
progressbar.start(1000)
um sie nebenläufig ausführen zu lassen, habe ich sie folgendermaßen aufgerufen:
die Progressbar läuft auch los, allerdings wird folgende Fehlermeldung ausgegeben und das Programm beendet:
Code: Alles auswählen
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:\Python27\GUI\GUI_1802.py", line 109, in consistency_check
Thread = thread(target=progress())
TypeError: 'module' object is not callable
was ich nicht verstehe ist, dass die Progressbar überhaupt losläuft... wie kann ich diesen Fehler umgehen?
Vielen Dank!
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Donnerstag 20. Februar 2014, 12:09
von pillmuncher
1) Du sollst nicht das
thread-Modul verwenden, sondern das
threading-Modul. BlackJack hat dir das bereits mitgeteilt.
2) In
threading gibt es eine Klasse
Thread. Die musst du verwenden. Sie heißt nicht
thread.
3) Das ganze tkinter-Zeugs muss im Haupt-Thread laufen. Aus einem zweiten Thread heraus direkt GUI-Manipulationen durchzuführen wird zu Problemen führen, weil tkinter, wie alle GUI Libs, bei sowas durcheinander kommt. Verwende dazu
queue.Queue und verschicke darüber Nachrichten und Daten zwischen den einzelnen Threads.
4) Du musst die Funktion
progress an
Thread(...) übergeben. Statt dessen rufst du sie momentan auf und übergibst das Ergebnis dieses Aufrufs. Guckstu:
Code: Alles auswählen
>>> def foo():
... return 'hey!'
...
>>> foo
<function foo at 0x7fedda04>
>>> foo()
'hey!'
5) Es gibt eine Code-Formatierung im Forum. Verwende sie.
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Freitag 21. Februar 2014, 15:09
von dominik123
Zunächst mal vielen Dank für die Antworten.
Ich importiere nun das threading- Modul.
Ist folgender Code richtig, um die Funktion progress an Thread() zu übergeben?
Code: Alles auswählen
thread= threading.Thread(target=progress)
thread.start()
Momentan sieht meine progress- Funktion folgender Maßen aus:
def progress():
progressbar = ttk.Progressbar(orient=HORIZONTAL, length=140, mode='indeterminate', maximum=10)
progressbar.grid(row=7, column=5, sticky=W)
progressbar.start(1000)
momentan würde ich also ein Teil des tkinter- Zeugs in einen extra Thread auslagern. Wie könnte ich meine progressbar auslagern, ohne automatisch einen teil des tkinter- Zeugs auszulagern und ohne dass diese sobald länger rechnende Funktionen abgearbeitet werden einfriert?
Ich hoffe meine Frage ist verständlich.
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Samstag 22. Februar 2014, 14:44
von pillmuncher
Hier ein kurzes Beispiel:
Code: Alles auswählen
try:
import Tkinter as tk # Python 2
import ttk
except ImportError:
import tkinter as tk # Python 3
import tkinter.ttk as ttk
from threading import Thread
from queue import Queue, Empty
import time
def make_progress(queue, maximum, step):
for i in range(maximum):
queue.put(1)
time.sleep(step)
class MainApp(tk.Frame):
def __init__(self, master, queue, maximum, update_interval):
self.queue = queue
self.update_interval = update_interval
tk.Frame.__init__(self, master)
self.progress = ttk.Progressbar(self, maximum=maximum)
self.progress.pack(expand=1, fill=tk.BOTH)
self.show_progress()
def show_progress(self):
try:
width = self.queue.get(False)
except Empty:
return
else:
self.progress.step(width)
self.update()
finally:
self.after(self.update_interval, self.show_progress)
if __name__ == '__main__':
q = Queue()
m = 10
u = 1
s = 2
t = Thread(target=make_progress, args=(q, m, s))
t.start()
root = tk.Tk()
app = MainApp(root, q, m, u)
app.pack(expand=1, fill=tk.BOTH)
root.mainloop()
t.join()
Es ist bloß auf die Schnelle und ohne viel Nachdenken zusammengehackt.
Re: Nebenläufigkeit von GUI und Messgerätkalibrierung realis
Verfasst: Dienstag 25. Februar 2014, 14:33
von dominik123
Vielen Dank! Jetzt läuft alles parallel...