Seite 1 von 1
Tkinter Programm nebenläufig
Verfasst: Freitag 16. Oktober 2020, 23:11
von ichbins
Hallo
ich finde eure Hilfe super. Jetzt kommt ein Problem mit Tkinter. Ich wollte vom Hauptprogramm Tkinter ausführen wo die Funktion werte ausgeführt wird und die Variaben aufgerufen werden. Das Problem ist jedoch dass ich das Programm schließen muss bevor ich die Werte bekomme und das Hauptprogramm die Werte weiter verarbeiten kann. So habe ich es mir vorgestellt es funktioniert nicht perfekt. Muss ich das mit threading lösen oder habt ihr eine bessere bzw. andere Problemlösung?
Danke!
Hauptprogramm
Code: Alles auswählen
import probe_gui
werte=probe_gui.Window().werte(None)
wert1=werte[0]
wert2=werte[1]
wert3=werte[2]
print(wert1, wert2, wert3)
while(True):
#Funktionen
pass
GUI
Code: Alles auswählen
import tkinter as tk
class Window():
def __init__(self):
self.root = tk.Tk()
self.root.geometry("600x400")
self.entries=[]
for column in range(0,4):
self.entry=tk.Entry(self.root, width=5)
self.entry.pack(side=tk.LEFT, anchor=tk.W)
self.entries.append(self.entry)
self.button=tk.Button(self.root, text='Auslesen', command=self.werte)
self.button.pack()
self.root.bind('<Return>', self.werte)
def werte(self, event):
auslesen=self.auslesen()
funktion1=self.funktion1()
funktion2=self.funktion2()
#print('Werte wurde gedrückt')
#print(auslesen, funktion1, funktion2)
return auslesen, funktion1, funktion2
def auslesen(self):
liste=[]
for x in self.entries:
#print(x)
#print(x.get())
x=x.get()
liste.append(x)
#print(liste)
return liste
def funktion1(self):
#print('Funktion1')
return 1
def funktion2(self):
#print('Funktion2')
return 2
graph=Window()
graph.root.mainloop()
Re: Tkinter Programm nebenläufig
Verfasst: Samstag 17. Oktober 2020, 01:30
von __blackjack__
@ichbins: Du ziehst das von der falschen Seite her auf. Die GUI-Hauptschleife ist das Hauptprogramm. Das ist das was man ausführt. Da muss sich Dein Code entweder direkt integrieren lassen, oder *der* läuft in einem Thread und die GUI kommuniziert per Queue(s) und `after()`-Methode mit dem Code. Die Geschäftslogikt ruft keinen GUI-Code auf.
Beim Importieren von Modulen darf kein Code ablaufen der mehr macht als Konstanten, Funktionen, und Klassen zu definieren. Bei Dir wird da sogar eine GUI ausgeführt.
Re: Tkinter Programm nebenläufig
Verfasst: Samstag 17. Oktober 2020, 20:29
von ichbins
Ich bin gerade am Überlegen ob es sich auszahlt in Thread und Queue einzuarbeiten oder ob es doch besser wäre sich in ein Webframework einzuarbeiten. Wird bei einem Webframework auch Thread und Queue benötigt oder geht es auch ohne.
Re: Tkinter Programm nebenläufig
Verfasst: Samstag 17. Oktober 2020, 20:43
von Sirius3
Das Problem ist doch das selbe: Du hast eine Ebene mit Benutzerinteraktion und parallel dazu irgendeine Berechnung. Also brauchst Du Threads und Queues.
Re: Tkinter Programm nebenläufig
Verfasst: Sonntag 18. Oktober 2020, 23:04
von ichbins
Irgendwie fehlt mir der Ansatz wie ich die Threads bei zwei Klassen bzw. zwei Dateien lösen kann. Habt ihr da ein Bsp. oder paar Tipps. Beim Start bleibt es in der Klasse Messinstrumente hängen.
LG
GUI
Code: Alles auswählen
import tkinter as tk
import probe_hauptprogramm
from threading import Thread
class Window():
def __init__(self):
self.root = tk.Tk()
self.root.geometry("600x400")
self.entries=[]
for column in range(0,4):
self.entry=tk.Entry(self.root, width=5)
self.entry.pack(side=tk.LEFT, anchor=tk.W)
self.entries.append(self.entry)
self.button=tk.Button(self.root, text='Auslesen', command=self.werte)
self.button.pack()
#self.root.bind('<Return>', self.werte)
def werte(self):
auslesen=self.auslesen()
funktion1=self.funktion1()
funktion2=self.funktion2()
probe_hauptprogramm.Messinstrumente(auslesen, funktion1, funktion2)
def auslesen(self):
liste=[]
for x in self.entries:
#print(x)
#print(x.get())
x=x.get()
liste.append(x)
#print(liste)
return liste
def funktion1(self):
#print('Funktion1')
return 1
def funktion2(self):
#print('Funktion2')
return 2
if __name__=='__main__':
graph=Window()
graph.root.mainloop()
x = Thread(graph)
x.start()
Messprogramm
Code: Alles auswählen
from time import sleep
from threading import Thread
class Messinstrumente:
def __init(self, auslesen, funk1, funk2):
self.lesen=auslesen
self.function1=funk1
self.function2=funk2
print(self.lesen, self.function1, self.function2)
x = Thread()
x.start()
#Hauptprogramm
while(True):
#Funktionen
print('programm wird ausgeführt´')
sleep(4)
try:
print(self.lesen)
print(self.function1)
print(self.function2)
except:
print('Fehler')
Re: Tkinter Programm nebenläufig
Verfasst: Montag 19. Oktober 2020, 02:03
von __blackjack__
@ichbins: Das sieht nach programmieren nach raten aus. Ein `Thread`-Objekt erstellen dem weder ein `target` mitgegeben wurde noch die `run()`-Methode überschrieben wurde macht einfach gar nichts wenn man diesen Thread mit `start()` startet. Also da wird ein Thread gestartet der dann auch gleich wieder beendet ist, weil der ja nix macht.
Und dann folgt auf Modulebene eine Endlosschleife bei der Du die Ausnahme die da unweigerlich auftritt, weil `self` nirgends definiert ist, über ein nacktes ``except:`` in eine absolut nicht hilfreiche Ausgabe des Wortes "Fehler" behandelst. Keine nackten ``except:``\s es sei denn man protokolliert die Ausnahme samt Traceback und es ist tatsächlich sinnvoll möglich an der Stelle *alle* Ausnahmen einfach zu ignorieren und so weiter zu machen, als wäre nichts passiert.
Das ganze passiert schon beim importieren von `probe_hauptprogramm` weil Code auf Klassenebene ausgeführt wird wenn die ``class``-Anweisung ausgeführt wird.
Ich sehe auch noch nicht so ganz ob/warum das eine Klasse sein muss.
Re: Tkinter Programm nebenläufig
Verfasst: Montag 19. Oktober 2020, 16:24
von ichbins
Da es nicht so funktioniert hat wie ich dachte, war es bisschen programmieren nach raten. Deswegen habe ich gemeint ein Bsp. wäre nicht schlecht. Ich habe es bisschen geändert, aber bei tkinter bleibt der Button noch immer blockiert.
Du hast gemeint ein Modul sollte immer eine Klasse oder Funktion bzw. Konstante sein. Letztendlich ist es das Hauptprogramm jedoch wird die Grafik zum Hauptprogramm. Ich könnte die 400 Zeilen in eine Funktion packen. Aber es kommt mir vor als ob es bisschen viele Zeilen für eine Funktion wären. Vielleicht könnte man das Programm noch in mehrere Funktionen unterteilen. Bzw. wie hast du dir das vorgestellt.
Code: Alles auswählen
import tkinter as tk
import probe_hauptprogramm
from threading import Thread
class Window():
def __init__(self):
self.root = tk.Tk()
self.root.geometry("600x400")
self.entries=[]
for column in range(0,4):
self.entry=tk.Entry(self.root, width=5)
self.entry.pack(side=tk.LEFT, anchor=tk.W)
self.entries.append(self.entry)
self.button=tk.Button(self.root, text='Auslesen', command=self.werte)
self.button.pack()
#self.root.bind('<Return>', self.werte)
def werte(self):
auslesen=self.auslesen()
funktion1=self.funktion1()
funktion2=self.funktion2()
probe_hauptprogramm.messinstrumente(auslesen, funktion1, funktion2)
def auslesen(self):
liste=[]
for x in self.entries:
#print(x)
#print(x.get())
x=x.get()
liste.append(x)
#print(liste)
return liste
def funktion1(self):
#print('Funktion1')
return 1
def funktion2(self):
#print('Funktion2')
return 2
if __name__=='__main__':
graph=Window()
graph.root.mainloop()
x = Thread(target=graph)
x.start()
y = Thread(target=probe_hauptprogramm.messinstrumente)
y.start()
Code: Alles auswählen
from time import sleep
from threading import Thread
def messinstrumente(auslesen, funk1, funk2):
#Hauptprogramm
while(True):
#Funktionen
print('programm wird ausgeführt´')
sleep(4)
print(auslesen)
print(funk1)
print(funk2)
Re: Tkinter Programm nebenläufig
Verfasst: Montag 19. Oktober 2020, 17:03
von Sirius3
@ichbins: dass self.entry falsch ist, wurde Dir schon gesagt, dass `x` ein sehr schlechter Variablenname ist, wurde Dir schon gesagt.
Wenn Du von einem Thread mit einer GUI kommunizieren willst, brauchst Du eine Queue.
`messinstrumente` übergibst Du Funktionen, was nicht sein darf, weil aus Threads heraus keine GUI angesprochen werden darf.
Was hast Du Dir bei x = Thread(target=graph) gedacht? graph ist doch nicht ausführbar.
Nach mainloop darf kein Code mehr kommen.
Code: Alles auswählen
import tkinter as tk
from threading import Thread
from queue import Queue
def messinstrumente(queue):
print('programm wird ausgeführt´')
while True:
werte = queue.get()
print(werte)
class Window():
def __init__(self, queue):
self.queue = queue
self.root = tk.Tk()
self.entries = []
for column in range(4):
entry=tk.Entry(self.root, width=5)
entry.pack(side=tk.LEFT, anchor=tk.W)
self.entries.append(entry)
tk.Button(self.root, text='Auslesen', command=self.werte_uebertragen).pack()
def werte_uebertragen(self):
werte = [entry.get() for entry in self.entries]
self.queue.put(werte)
def main():
queue = Queue()
mess_thread = Thread(target=messinstrumente, args=(queue,))
graph = Window(queue)
graph.root.mainloop()
if __name__=='__main__':
main()
Re: Tkinter Programm nebenläufig
Verfasst: Montag 19. Oktober 2020, 17:26
von __blackjack__
@ichbins: Natürlich blockiert das, Du rufst da bei einem Klick auf die Schaltfläche eine Funktion auf die eine Endlosschleife enthält, also nie wieder zur GUI-Hauptschleife zurück kehrt.
Die Funktion macht auch nicht so wirklich Sinn, denn da werden alle vier Sekunden die gleiche Werte per `print()` ausgegeben.
Was ebenfalls blockiert ist die GUI-Hauptschleife, solange das Fenster angezeigt wird. Nach dem schliessen des Fensters versuchst Du das `Tk`-Objekt in einem Thread auszuführen, was nicht geht weil das nicht aufrufbar ist. Und die `probe_hauptprogramm.messinstrumente()`-Funktion ebenfalls in einem Thread auszuführen, was aber nicht klappen wird, weil die ja drei Argumente erwartet, die aber nicht bekommt. Und wie gesagt, sinnvoll ist das auch nicht bis in alle Ewigkeit alle vier Sekunden die gleichen Werte auszugeben.
Die Namensgebung ist auch teilweise sehr verwirrend. `auslesen` ist eine Liste und `funktion1` und `funktion2` sind ganze Zahlen — das ist extrem irreführend. Wie man an der Antwort von Sirius3 sehen kann. Bei `messinstrumente()` dann `funk1` und `funk2` macht es nicht besser. Auf welchen Frequenzen wird denn da gesendet? Auch `messinstrumente()` geht als Name nicht. Funktionsnamen beschreiben die Tätigkeit die von der Funktion (oder Methode) ausgeführt wird. `messinstrumente` ist keine Tätigkeit.
Ich habe nicht gemein ein Modul sollte immer eine Klasse, Funktion, oder Konstante sein. Also ”sein” schon mal gar nicht, denn ein Modul ist ein Modul. Der Code auf Modulebene sollte nur Konstanten, Funktionen, und Klassen definieren. Da sollte kein Code stehen der globale Variablen definiert oder gar das Hauptprogramm. Man muss ein Modul importieren können, ohne das dabei mehr passiert als eben jene Definitionen von Konstanten, Funktionen, und Klassen.
Wenn Du da 400 Zeilen stehen hast die etwas anderes machen, dann ist das definitiv falsch. Und definitiv nichts was man mit einer GUI verbinden/-wenden kann. Dazu muss das mindestens in Funktionen stehen, wenn nicht sogar auch eine eigene Klasse sein wenn es Zustand gibt, der über meherere Aufrufe von der GUI hinweg gemerkt werden muss. Vielleicht ginge auch eine Funktion die in einem Thread läuft und über Queues mit der GUI kommuniziert.
Die 400-Zeilen-Aussage macht mir so ein bisschen sorgen. Denn für GUI-Programmierung braucht man Klassen. Für Klassen muss man Funktionen drauf haben. Und Funktionen heisst kleine globalen Variablen. Und jetzt kommst Du und sagst Du hast da 400 Zeilen Code die offenbar nicht einmal in *einer* Funktion stecken. Dann hast Du erst einmal noch gar kein Problem mit GUI-Programmierung, denn da ist noch überhaupt nicht dran zu denken.
Re: Tkinter Programm nebenläufig
Verfasst: Montag 19. Oktober 2020, 22:37
von ichbins
Danke für die ausführlichen Antworten.
@Sirius3: Kann es sein dass am Code irgendetwas nicht stimmt? Es wird 'while True' nicht ausgeführt bzw. keine Ausgabe.
@Blackjack: funk1 und funk2 sind die Funktionen 1 und 2. Es geht darum die Werte die in den ganzen Entry Widgets sind, in der Funktion messinstrumente aufzurufen.
Es gibt das Hauptprogramm mit 400 Zeilen was man noch in Funktionen aufteilen könnte und ein Modul aus Funktionen mit ca. 600 Zeilen. Man kann ein Programm immer verschönern jedoch ist mir zuerst wichtig dass ich die Eingaben im GUI im Hauptprogramm aufrufen kann.
Re: Tkinter Programm nebenläufig
Verfasst: Montag 19. Oktober 2020, 23:12
von __blackjack__
@ichbins: `funk1` und `funk2` sind keine Funktionen sondern die ganzen Zahlen 1 und 2. Zahlen sind keine Funktionen. Darum ist das echt verwirrend die so zu benennen. Die Werte in den Entries kann man auch nicht ”aufrufen”. Aufrufen ist einen Ausdruck zu schreiben der etwas aufrufbares ergibt und dann dahinter runde Klammern, optional mit Argumenten. *Das* ist ein Aufruf. Das geht mit Zeichenketten (die stehen in den Entries) oder Zahlen nicht.
Es geht hier nicht ums verschönern. Sauber auf echte Funktionen aufteilen und keine globalen Variablen zu verwenden ist nicht irgendwie schön, sondern der normale Grundzustand. Wenn man nicht einmal da ist, macht es keinen Sinn darüber nachzudenken wie man da eine GUI drauf setzt, denn das geht schlicht nicht. Eine GUI kann nicht Code aufrufen der auf Modulebene steht, dazu *muss* der mindestens in Funktionen stecken. Und da man für die GUI sowieso Klassen braucht, gibt es auch keinerlei Ausreden woanders globale Variablen zu verwenden.
Falls Dein Hauptprogramm in einem eigenen Thread läuft muss das auch mindestens in einer Funktion stecken, denn Code auf Modulebene kann man nicht in einem anderen Thread laufen lassen (es sei denn man macht noch mehr Sachen die man einfach nicht macht!).
Der Code in dem Thread kann auch nicht einfach so auf die GUI zugreifen, der muss threadsicher mit dem Thread in dem die GUI läuft kommunizieren. Was in der Regel am einfachsten über Queues geht.
Bei dem was Du da gezeigt hast ist aber nicht ganz klar was Du überhaupt erreichen willst. Wenn nur alle vier Sekunden *kurz* irgend etwas gemacht werden soll, dann braucht man keine Threads sondern kann einfach die `after()`-Methode verwenden.
Re: Tkinter Programm nebenläufig
Verfasst: Dienstag 20. Oktober 2020, 20:03
von ichbins
Ich möchte erreichen dass beim Start des Programms die GUI angezeigt wird und das Hauptprogramm blockiert. Nachdem ich den Button drücke sollen die ganzen Werte aus den Entry Widgets an das Hauptprogramm übergeben werden und das Hauptprogramm starten. Somit kommt auch das Hauptprogramm in eine while True Schleife und läuft die ganze Zeit. Die GUI ist nur nebenbei offen. Falls ich wieder auf den Button drücke sollen die Aktualisierten Werte wieder an das Hauptprogramm übergeben werden und von neu starten bzw. einfach nur die aktualisierten Werte übernehmen und damit weiter rechnen bzw. das Hauptprogramm bearbeiten. Es sind auch Wartezeiten in der while Schleife die mehrere Sekunden machen aber es läuft die ganze Zeit. Das Problem ist halt wenn das Hauptprogramm läuft dass die GUI blockiert. Bei diesem Bsp. war ja bei sleep() der Button blockiert. Somit war auch die Rede dass ich Threads brauche und Queues kamen auch zu Wort.
Ich habe das Programm vom Sirius probiert aber es lief nicht ganz nach meiner Vorstellung. Wenn ich auf "Ausführen" drücke erschienen nie die Werte von print(werte).
Re: Tkinter Programm nebenläufig
Verfasst: Mittwoch 21. Oktober 2020, 07:21
von Sirius3
Da fehlt ja auch ein `mess_thread.start()`.
Und bei GUIs mußt Du umdenken. Das "Hauptprogramm" wie Du es nennst, läuft nebenbei, denn GUIs betrachten sich immer selbst als Hauptprogramm. Daran kann man nichts ändern. Und so wie Du das beschreibst, ist es ungefähr das, was ich geschrieben habe: Das Messprogramm läuft in einem Thread und kann regelmäßig die Queue abfragen, ob neue Werte eingetragen wurden.
Re: Tkinter Programm nebenläufig
Verfasst: Freitag 30. Oktober 2020, 22:52
von ichbins
Hallo
bei diesem Bsp. ist ja stop_thread eine Globale Variable. Wenn das Hauptprogramm in der selben Datei steht dann funktioniert es. Jedoch wenn ich das Hauptprogramm in eine eigene Datei schreibe nimmt es nicht den Wert aus dem main-Programm obwohl es eine Globale Variable ist. Wieso ist das so?
LG
gui_probe_threading
Code: Alles auswählen
class Window():
def __init__(self, queue):
self.queue=queue
self.root = tk.Tk()
self.root.geometry("600x400")
self.entries=[]
for column in range(0,4):
self.entry=tk.Entry(self.root, width=5)
self.entry.pack(side=tk.LEFT, anchor=tk.W)
self.entries.append(self.entry)
self.button=tk.Button(self.root, text='Auslesen', command=self.werte)
self.button.pack()
#self.root.bind('<Return>', self.werte)
def werte(self):
werte=[]
werte.append(self.auslesen())
werte.append(self.funktion1())
werte.append(self.funktion2())
self.queue.put(werte)
def auslesen(self):
liste=[]
for x in self.entries:
#print(x)
#print(x.get())
x=x.get()
liste.append(x)
#print(liste)
return liste
def funktion1(self):
#print('Funktion1')
return 1
def funktion2(self):
#print('Funktion2')
return 2
global stop_thread
stop_thread=False
if __name__=='__main__':
queue=Queue()
my_thread=Thread(target=gui_probe_hauptprogramm.messprozess, args=(queue, ))
my_thread.start()
graph=Window(queue)
graph.root.mainloop()
stop_thread=True
gui_probe_hauptprogramm
Code: Alles auswählen
def messprozess(queue):
werte = queue.get()
print('programm wird ausgeführt´')
while True:
print(werte)
sleep(3)
if queue.empty() == False:
print('Empty voll')
werte=queue.get()
if gui_probe_threading.stop_thread!=False:
break
Re: Tkinter Programm nebenläufig
Verfasst: Freitag 30. Oktober 2020, 23:20
von __blackjack__
@ichbins: Vergiss bitte ``global``. Auf Modulebene hat das zudem sowieso keinerlei Effekt.
Warum rufst Du `queue.get()` vor der Schleife auf? Der Aufruf sollte nur einmal, in der Schleife stehen. Und auch grundsätzlich, nicht nur wenn `empty()` den Wert `False` liefert. Das beenden macht man dann nicht über eine extra Variable sondern man schickt über die Queue einen Wert der signalisiert, dass der Thread sich beenden soll.
Vergleiche mit literalen Wahrheitswerten macht man nicht. Da kommt nur wieder ein Wahrheitswert bei heraus. Entweder der den man sowieso schon hatte — dann kann man den auch gleich verwenden — oder das Gegenteil. Für den Fall gibt es ``not``.
Re: Tkinter Programm nebenläufig
Verfasst: Sonntag 1. November 2020, 13:24
von ichbins
queue.get ruf ich vor der Schleife auf um zu blockieren und alle Daten zu bekommen wie z.B. eine csv Datei zu erstellen bzw. fortzusetzen usw. In der while True Schleife verwende ich queue.get falls die Daten aktualisiert werden. Danach wird if queue.empty() verwendet damit queue.get nur blockiert falls neue Werte gesetzt wurden und Auslesen betätigt wird.
Wenn ich lese if queue.empty, habe ich mir manchmal die Frage gestellt was verglichen wird. Mit den literalen Wahrheitswerten war es irgendwie leserlicher für mich.
Re: Tkinter Programm nebenläufig
Verfasst: Sonntag 1. November 2020, 14:09
von __blackjack__
@ichbins: Tja rethorische Fragen.

Ich wollte eigentlich nicht wissen warum Du das aufrufst, *Du* solltest Dich das fragen und zu dem Schluss kommen, dass das unsinnig ist. Die Queue ist zur Kommunikation da, damit man keine globalen Variablen benutzen muss. Wenn Du da nebenher dann doch wieder noch eine globale Variable rein bastelst über die parallel zur Queue etwas kommuniziert werden soll, dann hätte man sich die Queue sparen können.
Bei ``if queue.empty()`:`` wird gar nichts verglichen. Da muss auch nichts verglichen werden. Darum muss man da auch wirklich nichts vergleichen. Es macht keinen Sinn. Es macht den Code nicht klarer. Da muss ein Ausdruck stehen der zu „wahr“ oder „falsch“ ausgewertet wird. Das muss kein Vergleich sein. Wenn man das liest, heisst das „Falls Queue leer, dann …“. Das ist IMHO ziemlich deutlich.
Re: Tkinter Programm nebenläufig
Verfasst: Dienstag 3. November 2020, 11:51
von ichbins
Mir ist noch nicht ganz klar wie Threads und Queue angewendet werden. Wieso ist es unsinnig? Ich habe es versucht mit diesem Code aber es passt nicht.
Code: Alles auswählen
import tkinter as tk
import gui_probe_hauptprogramm
from threading import Thread
from queue import Queue
import os
from time import sleep
class Window():
def __init__(self, queue):
self.queue=queue
self.root = tk.Tk()
self.root.geometry("600x400")
self.entries=[]
for column in range(0,4):
self.entry=tk.Entry(self.root, width=5)
self.entry.pack(side=tk.LEFT, anchor=tk.W)
self.entries.append(self.entry)
self.button=tk.Button(self.root, text='Auslesen', command=self.werte)
self.button.pack()
#self.root.bind('<Return>', self.werte)
def werte(self):
werte=[]
werte.append(self.auslesen())
werte.append(self.funktion1())
werte.append(self.funktion2())
self.queue.put(werte)
def auslesen(self):
liste=[]
for x in self.entries:
#print(x)
#print(x.get())
x=x.get()
liste.append(x)
#print(liste)
return liste
def funktion1(self):
#print('Funktion1')
return 1
def funktion2(self):
#print('Funktion2')
return 2
if __name__=='__main__':
stop_thread=False
queue=Queue()
my_thread=Thread(target=gui_probe_hauptprogramm.messinstrumente, args=(queue, stop_thread))
my_thread.start()
graph=Window(queue)
#graph.root.protocol('WM_DELETE_WINDOW', thread_stop)
graph.root.mainloop()
stop_thread=True
queue.put(stop_thread)
Code: Alles auswählen
def messinstrumente(queue, stop_thread):
#print(werte)
werte=queue.get()
print(werte)
print('programm wird ausgeführt´')
#Hauptprogramm
while(True):
#Funktionen
print(werte[0], werte[1], werte[2])
sleep(4)
if not queue.empty():
print('if wird ausgeführt')
werte=queue.get()
if stop_thread:
print('while wird abgebrochen')
break
Re: Tkinter Programm nebenläufig
Verfasst: Dienstag 3. November 2020, 12:27
von Sirius3
Das Problem ist, dass wir Dein messinstrument nicht kennen, und so der Code halt wenig Sinn macht.
Ein Modul gui_probe_hauptprogramm zu nennen, das explizit ja nichts mit der GUI zu tun haben soll, ist komisch.
Ein Modul gui_probe_hauptprogramm zu nennen, das explizit nicht das Hauptprogramm ist, sondern nebenläufig, ist komisch.
In __init__: wie oft soll ich noch schreibe, dass das Binden eines Wertes an ein Attribut innerhalb einer for-Schleife selten sinnvoll ist. entry ist und bleibt und wird immer eine lokale Variable bleiben.
In Methode werte: eine Methode sollte nicht wie eine Variable heißen. Wenn die Anzahl der Elemente einer Liste fix ist, dann erzeugt man gleich die Liste mit Elementen.
In auslesen: x ist ein schlechter Name für ein Entry und das bleibt es auch, egal wie oft Du das noch nicht berücksichtigst.
Das Argument stop_thread ist unsinnig, weil es immer False ist. my_ ist ein unsinniges Präfix.
Code: Alles auswählen
import tkinter as tk
from threading import Thread
from queue import Queue
from time import sleep
def messinstrumente(queue):
should_stop, werte = queue.get()
print(werte)
print('programm wird ausgeführt´')
while True:
#Funktionen
print(werte[0], werte[1], werte[2])
sleep(4)
if not queue.empty():
print('if wird ausgeführt')
should_stop, werte = queue.get()
if should_stop:
print('while wird abgebrochen')
break
class Window():
def __init__(self, queue):
self.queue = queue
self.root = tk.Tk()
self.entries = []
for column in range(0,4):
entry = tk.Entry(self.root, width=5)
entry.pack(side=tk.LEFT, anchor=tk.W)
entries.append(entry)
tk.Button(self.root, text='Auslesen', command=self.sende_werte).pack()
def sende_werte(self):
werte = [self.auslesen(), self.funktion1(), self.funktion2()]
self.queue.put((False, werte))
def auslesen(self):
return [
entry.get()
for entry in self.entries
]
def funktion1(self):
#print('Funktion1')
return 1
def funktion2(self):
#print('Funktion2')
return 2
if __name__=='__main__':
queue = Queue()
messinstrumente_thread = Thread(target=gui_probe_hauptprogramm.messinstrumente, args=(queue, ))
messinstrumente_thread.start()
graph = Window(queue)
graph.root.mainloop()
queue.put((True, None))