Hi, ich bin nicht so faul...wollte nur "rasch" einen PNG-File im selben Script erzeugen...was aber nicht so recht funktioniert hat.
@ Sirius3 Hintergrundthread ist leicht gesagt, aber man muß es auch verstehen...ich gebe mir etwas Zeit!
Danke Allen! Gruß Rainer
errechnete Werte in Canvas anzeigen
Erzeugen ist eigentlich auch kein Problem mit Image.new. Das hätte dann statt so
so ausgesehen:
Bei dem kleinen 4 x 4 halt ähnlich, so dass nicht unbedingt echte Images geladen werden müssen. Hatte nur kein Beispiel zu liegen, weil ich nur mit Animationen für Videos experimentiert hatte und da dann, falls es einmal fertig werden sollte, echte Images als Hintergrundmotive verwendet werden sollen und keine leeren Flächen.
Code: Alles auswählen
self.leinwand_image = Image.open(self.leinwand)
self.hintergrung = ImageTk.PhotoImage(self.leinwand_image)
Code: Alles auswählen
self.leinwand_image = Image.new("RGB", (500, 400), (246, 230, 190))
self.hintergrung = ImageTk.PhotoImage(self.leinwand_image)
Hallo Melewo, habe dein Beispiel jetzt nachvollziehen können, danke. Dir ist aber schon klar, dass das nicht mein Problem löst...
@__deets__, habe mal versucht, rauszukriegen, wie man die berechneten Werte aus einem zweiten Thread zum Eventhandler in der "root.mainloop()" rüberschaffen könnte. Im Tkinter-Tutorial empfehlen sie, die Threads über globale Variable zu verbinden. Leider wird das aber in nur wenigen Zeilen abgehandelt und es ist ja überall zu lesen, dass globale Variablen schlechter Programmierstil ist....weiterhin habe ich versucht zu verstehen, wie die Pipes funktionieren und da bin ich noch nicht durchgestiegen. Was mir jedoch klar wird, ist, dass ich in der "after-Schleife" auf "irgendwas" pollen kann/muß. D.h. also, der Eventhandler lauert auf seine Events und meine Schleife lauert auf "meinen Event". Beschreibt das in etwa die Situation, auf der ich dann aufbauen kann??
Vielen Dank, Rainer
@__deets__, habe mal versucht, rauszukriegen, wie man die berechneten Werte aus einem zweiten Thread zum Eventhandler in der "root.mainloop()" rüberschaffen könnte. Im Tkinter-Tutorial empfehlen sie, die Threads über globale Variable zu verbinden. Leider wird das aber in nur wenigen Zeilen abgehandelt und es ist ja überall zu lesen, dass globale Variablen schlechter Programmierstil ist....weiterhin habe ich versucht zu verstehen, wie die Pipes funktionieren und da bin ich noch nicht durchgestiegen. Was mir jedoch klar wird, ist, dass ich in der "after-Schleife" auf "irgendwas" pollen kann/muß. D.h. also, der Eventhandler lauert auf seine Events und meine Schleife lauert auf "meinen Event". Beschreibt das in etwa die Situation, auf der ich dann aufbauen kann??
Vielen Dank, Rainer
Eine Queue ist erstmal nichts anderes als eine Liste, an der man am einen Ende was reinstopft, und am anderen Ende was rausholt.
Und in tkinter schreibt man sich nun eine after-Methode, welche
- prueft, ob etwas in der Queue ist.
- wenn ja, es rausholt und dann ein GUI-update anstoesst.
Die muss halt im gewuenschten Interval aufgerufen werden.
Ein anderer Thread kann die Queue dann mit Daten bestuecken.
Ein Beispiel findet sich natuerlich auch hier im Forum, zB hier: viewtopic.php?t=40146 - letzten Post anschauen.
Streng genommen ist die Queue auch dort globaler Zustand, aber das muss nicht so sein - deine Quellen haben in dieser Beziehung nicht recht. Und der Post zeigt auch, wie es gemacht wird: man muss halt die Instanz der Queue sowohl an die GUI-Klassen uebergeben, als auch an den Thread. Danach braucht niemand anderes darauf eine Referenz.
Und in tkinter schreibt man sich nun eine after-Methode, welche
- prueft, ob etwas in der Queue ist.
- wenn ja, es rausholt und dann ein GUI-update anstoesst.
Die muss halt im gewuenschten Interval aufgerufen werden.
Ein anderer Thread kann die Queue dann mit Daten bestuecken.
Ein Beispiel findet sich natuerlich auch hier im Forum, zB hier: viewtopic.php?t=40146 - letzten Post anschauen.
Streng genommen ist die Queue auch dort globaler Zustand, aber das muss nicht so sein - deine Quellen haben in dieser Beziehung nicht recht. Und der Post zeigt auch, wie es gemacht wird: man muss halt die Instanz der Queue sowohl an die GUI-Klassen uebergeben, als auch an den Thread. Danach braucht niemand anderes darauf eine Referenz.
@pyzip: Und mit queue hast Du Dich noch nicht befasst?
Liest sich für mich zumindest so, als ob Du Dir das wirklich einmal näher betrachten solltest.
Liest sich für mich zumindest so, als ob Du Dir das wirklich einmal näher betrachten solltest.
https://docs.python.org/3/library/queue.htmlThe queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads.
Hallo, vielen Dank für den Tip. Nein, über Queue bin ich bisher noch nicht gestolpert! Im Tutorial, dass ich hauptsächlich benutze, ist mir jedenfalls nichts aufgefallen. (https://www.python-kurs.eu/) Aber das ist doch ein Ansatz. Auch wenn ich heute Abend den Spyder3 vielleicht nicht mehr anwerfe...
Gruß Rainer
Gruß Rainer
Also ich hab' mir da mal gerade das Kapitel ueber OO angeschaut - und erschauere... https://www.python-kurs.eu/python3_klassen.php strotzt nur so von Unfug.
Und Queue/queue kommt in meinem Beispiel (bzw dem Link) zur Anwendung.
Und Queue/queue kommt in meinem Beispiel (bzw dem Link) zur Anwendung.
Es gibt nicht das eine Tutorial, in dem alles ausgesprochen gut und zugleich leichtverständlich für Einsteiger erklärt wird. Zumindest kenne ich keins. Wenn, so wurden die Tutorials von https://docs.python.org/3/tutorial/index.html wiederholt empfohlen. Wer nach einem Ansatz zur Lösung eines einzelnen Problems sucht, wird oft bei stackoverflow.com fündig, nicht aber um die Grundlagen zu lernen.
Und was die Beschreibung einer Queue anbelangt, da finde ich die von __deets__ weiter oben verfasste ganz gut und halte diese für allgemein verständlich. Selbiges betrifft in diesem Zusammenhang deren Verwendung in Tkinter. Damit kann man etwas anfangen, kann erfassen, was eine Queue ist, kann sich das verlinkte Beispiel ansehen und nach weiteren Beispielen suchen.
Ich würde jetzt an Deiner Stelle einfach mit einem abgemagerten Tkinter-Beispiel beginnen, in dem weder Canvas noch sonstige Images verwendet werden, nur mit after und einer einfachen Ausgabe. Dann würde ich eine Testreihe machen, wie ich in Tkinter mit einer Queue die Daten übernehmen und erst einmal nur ausgeben könnte.
Und wenn Du das geschafft hast, könntest Du Dir in einem zweiten Schritt immer noch überlegen, wie Du die übernommenen Daten am besten visualisieren könntest.
Und was die Beschreibung einer Queue anbelangt, da finde ich die von __deets__ weiter oben verfasste ganz gut und halte diese für allgemein verständlich. Selbiges betrifft in diesem Zusammenhang deren Verwendung in Tkinter. Damit kann man etwas anfangen, kann erfassen, was eine Queue ist, kann sich das verlinkte Beispiel ansehen und nach weiteren Beispielen suchen.
Ich würde jetzt an Deiner Stelle einfach mit einem abgemagerten Tkinter-Beispiel beginnen, in dem weder Canvas noch sonstige Images verwendet werden, nur mit after und einer einfachen Ausgabe. Dann würde ich eine Testreihe machen, wie ich in Tkinter mit einer Queue die Daten übernehmen und erst einmal nur ausgeben könnte.
Und wenn Du das geschafft hast, könntest Du Dir in einem zweiten Schritt immer noch überlegen, wie Du die übernommenen Daten am besten visualisieren könntest.
Hallo, hat leider etwas gedauert. Aber ich habe nun das Problem prinzipiell gelöst. Allerdings steigt Spyder manchmal mit der Meldung "Tcl_AsyncDelete: async handler deleted by the wrong thread" aus. Nach jedem zweiten Start des Programms, geht es wieder weiter. Werden meine beiden Threads nicht richtig beendet? Hier das Script
[code#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 28 14:31:27 2017
@author: zip
"""
import tkinter as tk
import time
from threading import Thread
import queue
q = queue.Queue()
class Diagramm(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.pack()
self.master = master
self.master.title("Diagramm")
self.DIAG_X_OFFSET_L = 100
self.DIAG_X_OFFSET_R = 50
self.DIAG_Y_OFFSET_O = 20
self.DIAG_Y_OFFSET_U = 150
self.M_WIDTH = 810
self.M_HEIGHT = 610
self.C_WIDTH = self.M_WIDTH - 10
self.C_HEIGHT = self.M_HEIGHT - 10
self.DIAG_WIDTH = self.M_WIDTH - self.DIAG_X_OFFSET_L - self.DIAG_X_OFFSET_R
self.DIAG_HEIGHT = self.M_HEIGHT - self.DIAG_Y_OFFSET_O - self.DIAG_Y_OFFSET_U
self.create_widgets()
self.placeWindow()
self.create_canvas()
self.a = self.y_achse_txt(0, 1)
self.zeichne_diagramm(self.DIAG_X_OFFSET_L, self.DIAG_Y_OFFSET_O,
self.C_WIDTH - self.DIAG_X_OFFSET_R,
self.C_HEIGHT - self.DIAG_Y_OFFSET_U, self.a)
self.get_koordinate()
def placeWindow(self):
x = 100
y = 200
self.master.geometry('%dx%d+%d+%d' % (self.M_WIDTH, self.M_HEIGHT, x, y))
def create_widgets(self):
# x = 150
# y = 150
self.canvas = tk.Canvas(self, width=(self.C_WIDTH), height=(self.C_HEIGHT))
self.canvas.pack()
# self.start_button = tk.Button(self, text="start", command=self.greet)
# self.start_button.pack()
##b = Button(master, text="Help", state=DISABLED)
# self.close_button = tk.Button(self, text="Close", state="disabled",
# command=self.master.destroy)#active, disabled, or normal
# self.close_button.pack()# config(**options)
def greet(self):
print("Greetings!")
self.close_button.config(state="active")
def y_achse_txt(self, null_p, max_p):
#Y- Beschriftung berechnen von 0_p bis max_p
#gibt String-Liste zurück!
self.y_txt=[]
for i in range(null_p, (max_p * 10) + 1):
i=i/10
a='{0:.2f}'.format(i)
self.y_txt.append(a)
return self.y_txt
def create_canvas(self):
canvas = tk.Canvas(self.master, width=self.C_WIDTH,
height=self.C_WIDTH)
canvas.pack()
def zeichne_diagramm(self, x_1, y_1, x_2, y_2, y_txt):
x = int((y_2 - y_1)/10)
index=0
self.canvas.create_rectangle(x_1, y_1, x_2, y_2, fill="white",width=3)
for i in range(y_2, y_1 - x, -x):
self.canvas.create_line(x_1, i, x_2, i, fill="black", width=1)
self.canvas.create_text(x_1 - 20, i, text=y_txt[index])
index += 1
def zeichne_kreis(self, x, y, farbe="red"):
#kleiner Kreis an Pos. x, y
return self.canvas.create_oval(x - 2, y - 2, x + 2, y + 2, fill=farbe)
def zeichne_punkt(self, g):
self.zeichne_kreis((150 + (g * 10)), (150 + (g * 10)), farbe="red")
def get_koordinate(self):
while not q.empty():
a = q.get()
a = int(a)
self.zeichne_punkt(a)
time.sleep(0.1)
self.canvas.after(1, self.get_koordinate)
def counter1():
for i in range(1, 6):
q.put(i)
time.sleep(5)
#def sleeper(i):
# print("thread %d sleeps for 5 seconds" % i)
# time.sleep(5)
# print("thread %d woke up" % i)
def diagramm_fenster():
root = tk.Tk()
dia = Diagramm(master=root)
dia.mainloop()
def main():
tc = Thread(target=counter1)
tw = Thread(target=diagramm_fenster)
tw.start()
tc.start()
# eingabe = input("Ihre Eingabe? ")
if __name__ == '__main__':
main()][/code]
[code#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 28 14:31:27 2017
@author: zip
"""
import tkinter as tk
import time
from threading import Thread
import queue
q = queue.Queue()
class Diagramm(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.pack()
self.master = master
self.master.title("Diagramm")
self.DIAG_X_OFFSET_L = 100
self.DIAG_X_OFFSET_R = 50
self.DIAG_Y_OFFSET_O = 20
self.DIAG_Y_OFFSET_U = 150
self.M_WIDTH = 810
self.M_HEIGHT = 610
self.C_WIDTH = self.M_WIDTH - 10
self.C_HEIGHT = self.M_HEIGHT - 10
self.DIAG_WIDTH = self.M_WIDTH - self.DIAG_X_OFFSET_L - self.DIAG_X_OFFSET_R
self.DIAG_HEIGHT = self.M_HEIGHT - self.DIAG_Y_OFFSET_O - self.DIAG_Y_OFFSET_U
self.create_widgets()
self.placeWindow()
self.create_canvas()
self.a = self.y_achse_txt(0, 1)
self.zeichne_diagramm(self.DIAG_X_OFFSET_L, self.DIAG_Y_OFFSET_O,
self.C_WIDTH - self.DIAG_X_OFFSET_R,
self.C_HEIGHT - self.DIAG_Y_OFFSET_U, self.a)
self.get_koordinate()
def placeWindow(self):
x = 100
y = 200
self.master.geometry('%dx%d+%d+%d' % (self.M_WIDTH, self.M_HEIGHT, x, y))
def create_widgets(self):
# x = 150
# y = 150
self.canvas = tk.Canvas(self, width=(self.C_WIDTH), height=(self.C_HEIGHT))
self.canvas.pack()
# self.start_button = tk.Button(self, text="start", command=self.greet)
# self.start_button.pack()
##b = Button(master, text="Help", state=DISABLED)
# self.close_button = tk.Button(self, text="Close", state="disabled",
# command=self.master.destroy)#active, disabled, or normal
# self.close_button.pack()# config(**options)
def greet(self):
print("Greetings!")
self.close_button.config(state="active")
def y_achse_txt(self, null_p, max_p):
#Y- Beschriftung berechnen von 0_p bis max_p
#gibt String-Liste zurück!
self.y_txt=[]
for i in range(null_p, (max_p * 10) + 1):
i=i/10
a='{0:.2f}'.format(i)
self.y_txt.append(a)
return self.y_txt
def create_canvas(self):
canvas = tk.Canvas(self.master, width=self.C_WIDTH,
height=self.C_WIDTH)
canvas.pack()
def zeichne_diagramm(self, x_1, y_1, x_2, y_2, y_txt):
x = int((y_2 - y_1)/10)
index=0
self.canvas.create_rectangle(x_1, y_1, x_2, y_2, fill="white",width=3)
for i in range(y_2, y_1 - x, -x):
self.canvas.create_line(x_1, i, x_2, i, fill="black", width=1)
self.canvas.create_text(x_1 - 20, i, text=y_txt[index])
index += 1
def zeichne_kreis(self, x, y, farbe="red"):
#kleiner Kreis an Pos. x, y
return self.canvas.create_oval(x - 2, y - 2, x + 2, y + 2, fill=farbe)
def zeichne_punkt(self, g):
self.zeichne_kreis((150 + (g * 10)), (150 + (g * 10)), farbe="red")
def get_koordinate(self):
while not q.empty():
a = q.get()
a = int(a)
self.zeichne_punkt(a)
time.sleep(0.1)
self.canvas.after(1, self.get_koordinate)
def counter1():
for i in range(1, 6):
q.put(i)
time.sleep(5)
#def sleeper(i):
# print("thread %d sleeps for 5 seconds" % i)
# time.sleep(5)
# print("thread %d woke up" % i)
def diagramm_fenster():
root = tk.Tk()
dia = Diagramm(master=root)
dia.mainloop()
def main():
tc = Thread(target=counter1)
tw = Thread(target=diagramm_fenster)
tw.start()
tc.start()
# eingabe = input("Ihre Eingabe? ")
if __name__ == '__main__':
main()][/code]
Es gibt hier eine Vorschau-Funktion. Die solltest du nutzen um zu verhindern, dass dein Code so falsch formatiert wird.
Was man entziffern kann ist, das du die GUI in einem neuen Thread startest. Das geht nicht, und deine Fehlermeldung ist auch ein Hinweis darauf. Das du ueberhaupt etwas zu sehen bekommst ist Zufall, und nicht garantiert.
Ich verstehe auch gar nicht, warum du den ueberhaupt startest, wenn der Main-Thread dann einfach vor sich hin wartet.
GUI darf NUR aus dem main-thread, also einfach dem Thread den es eh immer gibt, angefasst werden. Nirgends sonst.
Nimm das also raus, und spring einfach direkt dein diagramm_fenster() ein - nach start des counter-Threads
Warum du dann in get_koordinate ein time.sleep einlegst ist auch nicht ersichtlich.
Was man entziffern kann ist, das du die GUI in einem neuen Thread startest. Das geht nicht, und deine Fehlermeldung ist auch ein Hinweis darauf. Das du ueberhaupt etwas zu sehen bekommst ist Zufall, und nicht garantiert.
Ich verstehe auch gar nicht, warum du den ueberhaupt startest, wenn der Main-Thread dann einfach vor sich hin wartet.
GUI darf NUR aus dem main-thread, also einfach dem Thread den es eh immer gibt, angefasst werden. Nirgends sonst.
Nimm das also raus, und spring einfach direkt dein diagramm_fenster() ein - nach start des counter-Threads
Warum du dann in get_koordinate ein time.sleep einlegst ist auch nicht ersichtlich.
@pyzip: Tk-Objekte sollten prinzipiell nur vom Hauptthread erzeugt werden. Warum erzeugst Du einen `diagramm_fenster`-Thread?
Zeile 14: Queue q sollte nicht global sein, sondern als Argument dem counter-Thread und dem Fenster übergeben werden.
Zeile 23: pack gehört hier nicht hin, sondern in die aufrufende Funktion
Zeile 26ff: Konstanten sollten auf Klassen- oder Modulebene definiert werden und nicht in __init__.
`placeWindow` sollte `place_window` heißen und muß eigentlich gar keine eigene Funktion sein. Wenn plaziert wird, gehört das in main. Warum sind `x` und `y` hier nicht als Konstanten definiert, sondern direkt als Zahlen?
Zeile 55: alle Attribute sollten in __init__ eingeführt werden. Die Funktion ist eigentlich unnötig und kann in __init__ integriert werden.
Zeile 69: in `y_achse_txt` sollte y_txt nicht definiert werden, zumal das Ergebnis in `__init__` an a (ein schlechter Name) gebunden wird. Damit ist die Funktion nicht mehr von self abhängig und könnte raus aus der Klasse.
Zeile 79: nochmal ein canvas? warum? wird nicht benutzt!
Zeile 103: Der Name get_koordinate läßt erwarten, dass irgendwas ermittelt wird; sollte besser `process_coordinates` heißen.
Zeile 107: Das was in die Queue gesteckt wird, ist schon eine Zahl. Weg damit.
Zeile 109: was soll das sleep? Das darf in GUI-Programmen nicht vorkommen!
Zeile 132ff: Leerzeilen unnötig.
Ungetestet:
Zeile 14: Queue q sollte nicht global sein, sondern als Argument dem counter-Thread und dem Fenster übergeben werden.
Zeile 23: pack gehört hier nicht hin, sondern in die aufrufende Funktion
Zeile 26ff: Konstanten sollten auf Klassen- oder Modulebene definiert werden und nicht in __init__.
`placeWindow` sollte `place_window` heißen und muß eigentlich gar keine eigene Funktion sein. Wenn plaziert wird, gehört das in main. Warum sind `x` und `y` hier nicht als Konstanten definiert, sondern direkt als Zahlen?
Zeile 55: alle Attribute sollten in __init__ eingeführt werden. Die Funktion ist eigentlich unnötig und kann in __init__ integriert werden.
Zeile 69: in `y_achse_txt` sollte y_txt nicht definiert werden, zumal das Ergebnis in `__init__` an a (ein schlechter Name) gebunden wird. Damit ist die Funktion nicht mehr von self abhängig und könnte raus aus der Klasse.
Zeile 79: nochmal ein canvas? warum? wird nicht benutzt!
Zeile 103: Der Name get_koordinate läßt erwarten, dass irgendwas ermittelt wird; sollte besser `process_coordinates` heißen.
Zeile 107: Das was in die Queue gesteckt wird, ist schon eine Zahl. Weg damit.
Zeile 109: was soll das sleep? Das darf in GUI-Programmen nicht vorkommen!
Zeile 132ff: Leerzeilen unnötig.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 28 14:31:27 2017
@author: zip
"""
import tkinter as tk
import time
from threading import Thread
import queue
DIAG_X_OFFSET_L = 100
DIAG_X_OFFSET_R = 50
DIAG_Y_OFFSET_O = 20
DIAG_Y_OFFSET_U = 150
M_LEFT = 100
M_TOP = 200
M_WIDTH = 810
M_HEIGHT = 610
C_WIDTH = M_WIDTH - 10
C_HEIGHT = M_HEIGHT - 10
DIAG_WIDTH = M_WIDTH - DIAG_X_OFFSET_L - DIAG_X_OFFSET_R
DIAG_HEIGHT = M_HEIGHT - DIAG_Y_OFFSET_O - DIAG_Y_OFFSET_U
def get_y_axis_ticks(null_p, max_p):
#Y- Beschriftung berechnen von 0_p bis max_p
#gibt String-Liste zurück!
return ['{0:.2f}'.format(i/10)
for i in range(null_p, (max_p * 10) + 1)
]
class Diagramm(tk.Frame):
def __init__(self, queue, master):
super().__init__(master)
self.queue = queue
self.master = master
self.master.title("Diagramm")
self.canvas = tk.Canvas(self, width=C_WIDTH, height=C_HEIGHT)
self.canvas.pack()
ticks = get_y_axis_ticks(0, 1)
self.zeichne_diagramm(DIAG_X_OFFSET_L, DIAG_Y_OFFSET_O,
C_WIDTH - DIAG_X_OFFSET_R,
C_HEIGHT - DIAG_Y_OFFSET_U, ticks)
self.process_coordinates()
def zeichne_diagramm(self, x_1, y_1, x_2, y_2, ticks):
x = int((y_2 - y_1)/10)
self.canvas.create_rectangle(x_1, y_1, x_2, y_2, fill="white",width=3)
for tick, i in zip(ticks, range(y_2, y_1 - x, -x)):
self.canvas.create_line(x_1, i, x_2, i, fill="black", width=1)
self.canvas.create_text(x_1 - 20, i, text=tick)
def zeichne_kreis(self, x, y, farbe="red"):
#kleiner Kreis an Pos. x, y
return self.canvas.create_oval(x - 2, y - 2, x + 2, y + 2, fill=farbe)
def zeichne_punkt(self, g):
self.zeichne_kreis((150 + (g * 10)), (150 + (g * 10)), farbe="red")
def process_coordinates(self):
while not q.empty():
self.zeichne_punkt(q.get())
self.canvas.after(100, self.process_coordinates)
def counter1():
for i in range(1, 6):
q.put(i)
time.sleep(5)
def main():
q = queue.Queue()
tc = Thread(target=counter1, args=(q,))
root = tk.Tk()
dia = Diagramm(q, master=root)
dia.pack()
root.geometry('%dx%d+%d+%d' % (M_WIDTH, M_HEIGHT, M_LEFT, M_TOP))
root.mainloop()
if __name__ == '__main__':
main()
Hallo und vielen Dank, vor allem auch für die umfassende Korrektur von Sirius3! Wenn ich das Script laufen lasse, dann bekomme ich diesen Fehler. Muß ich "q" noch in der Klasse übergeben oder warum kennt er "q" nicht? Schätze mal, dass er dann "q" auch nicht in "counter1()" kennen wird...
File "/home/zip/py/treading-4.py", line 63, in process_coordinates
while not q.empty():
NameError: name 'q' is not defined
Das "sleep" habe ich gemacht, damit der Eventhandler vom Fenster auch mal dran kommt. Habe gelesen, dass "get" blockiert. Und dass ich mit meinem Window im Thread quasi doppelt gemoppelt habe, habe ich mir fast schon gedacht.
Und zum Schluß noch die Frage, was ich denn machen muß, um den Code "vernünftig" ins Forum zu kopieren. Wenn ich den Code aus Spyder kopiere, sind die Zeilennummern nicht drin, aber wenigstens die Einrückungen. Dass die hier auch verschwunden sind, ist mir gar nicht aufgefallen! Sorry...
Gruß Rainer
File "/home/zip/py/treading-4.py", line 63, in process_coordinates
while not q.empty():
NameError: name 'q' is not defined
Das "sleep" habe ich gemacht, damit der Eventhandler vom Fenster auch mal dran kommt. Habe gelesen, dass "get" blockiert. Und dass ich mit meinem Window im Thread quasi doppelt gemoppelt habe, habe ich mir fast schon gedacht.
Und zum Schluß noch die Frage, was ich denn machen muß, um den Code "vernünftig" ins Forum zu kopieren. Wenn ich den Code aus Spyder kopiere, sind die Zeilennummern nicht drin, aber wenigstens die Einrückungen. Dass die hier auch verschwunden sind, ist mir gar nicht aufgefallen! Sorry...
Gruß Rainer
@pyzip: dass in counter1 das Argument fehlt, `def counter1(q):`, hast Du sicher schon selbst herausgefunden. `queue.get` blockiert nicht, da Du ja vorher prüfst, dass auch wirklich ein Element in der Schlange wartet. Alternativ könnte man auch `get_nowait` verwenden und die Empty-Exception abfangen. Das `sleep` macht genau das Gegenteil, von dem, was Du erreichen willst; es blockiert die GUI.
Im Forum gibt es über dem Editfeld das Dropdown `Code auswählen`.
Im Forum gibt es über dem Editfeld das Dropdown `Code auswählen`.
@pyzip man sieht klar, dass du dem oeffnenden code-tag seine schliessende Klammer geklaut hast. Insofern ist das jetzt nicht weiter ein Mysterium. Spiel doch mal mit der Vorschau-Funktion, ich bin mir sicher das klappt.
Hallo. auch wenn ich mich jetzt völlig entblöde...es gibt kein DropDown "Code auswählen", es gibt nur "code" und dahin paste ich meinen code von Spyder.
Und zum Code an sich.
Die Klasse kennt "q"immer noch nicht!? Habe einfach keine Idee, was ich da machen soll.
Gruß Rainer
Und zum Code an sich.
Die Klasse kennt "q"immer noch nicht!? Habe einfach keine Idee, was ich da machen soll.
Gruß Rainer
Hi --deets--, also ich will mich ja jetzt nicht noch blöder darstellen, aber mit deiner Anweisung kann ich überhaupt nichts anfangen! Was verstehe ich nicht???? "Der code-button funktioniert auch, aber du musst schon die tags in ordnung lassen". Wie, wenn ich aus Spyder kopiere. Ich lass' da doch alles in Ordnung?
Rainer
Rainer