Guten Tag,
ich aktualisiere eine Anzeige mit after. Die sich selbst immer wieder aufrufende after-Funktion holt den Werte aus der Datenbankabfrage, die in einem separatem Modul ausgeführt wird. Der Modul muß dazu bei jeder Abholung neu ausgeführt werden um den Wert zu aktualisieren. Leider tut er das nicht. Wie kann ich das hinbekommen ?
tkinter after
- __blackjack__
- User
- Beiträge: 13931
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Nobima: Vorweg: Die Funktion ruft sich nicht selbst auf. Das wäre dann ja Rekursion. Die Funktion sagt mit `after()`, dass sie gerne nach einer gewissen Zeit wieder aufgerufen werden möchte. Beendet sich dann. Gibt also die Kontrolle wieder an die GUI-Hauptschleife zurück. Und wird dann nach der gewünschten Zeit (±) von der GUI-Hauptschleife erneut aufgerufen.
Module werden genau einmal ausgeführt: Wenn sie das erste mal importiert werden. Und dabei darf nichts passieren ausser das Konstanten, Funktionen, und Klassen definiert werden. Beim Import darf keine Datenbankverbindung aufgebaut werden und schon gar keine Abfrage von Daten gemacht werden. Die darin definierten Funktionen kannst Du aufrufen und Objekte aus den Klassen erstellen.
Module werden genau einmal ausgeführt: Wenn sie das erste mal importiert werden. Und dabei darf nichts passieren ausser das Konstanten, Funktionen, und Klassen definiert werden. Beim Import darf keine Datenbankverbindung aufgebaut werden und schon gar keine Abfrage von Daten gemacht werden. Die darin definierten Funktionen kannst Du aufrufen und Objekte aus den Klassen erstellen.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
Hallo,
ich bin mir nicht ganz sicher was du genau für ein Bsp. möchtest. Ich habe eins zu 'after' gefunden, das ich mal geschrieben habe:
Grüße
Dennis
ich bin mir nicht ganz sicher was du genau für ein Bsp. möchtest. Ich habe eins zu 'after' gefunden, das ich mal geschrieben habe:
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
from random import randint
class TemperaturDisplay(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
tk.Label(self, text='Außentempertur:').grid(row=0, column=0)
self.außentemperatur = tk.Label(self, text='0 °C')
self.außentemperatur.grid(row=1, column=0)
self.sensoren_auslesen()
def außentemperatur_aktualisieren(self, außentemperatur):
self.außentemperatur.config(text = f'{außentemperatur} °C')
def sensoren_auslesen(self):
außentemperatur = randint(0, 30)
self.außentemperatur_aktualisieren(außentemperatur)
self.after(1000, self.sensoren_auslesen)
def main():
root = tk.Tk()
root.title('Temperaturübersicht')
app = TemperaturDisplay(root)
app.pack()
app.mainloop()
if __name__ == "__main__":
main()
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Ich versuche, mich der Aufgabe mit ganz einfachen Scripten zu nähern.
Im Haupscript steht:
Im Modul "Modultest" steht:
Soweit funktioniert es periodisch. Leider wird außer dem großen Fenster noch ein kleines unerwünschtes Fenster mit dem Titel "tk #2" dargestellt. Außerdem möchte ich die Zufallszahl Z im Hauptscript verfügbar haben. Für eine Lösung bin ich dankbar.
Im Haupscript steht:
Code: Alles auswählen
import tkinter as tk
import Modultest
window = tk.Tk()
window.geometry('500x180')
window.title('TEST')
foo = Modultest.Foo()
foo.periodically()
window.mainloop()
Code: Alles auswählen
import tkinter as tk
import random
class Foo(tk.Tk):
def periodically(self):
Z = random.randint(0, 99)
print(Z)
self.after(2000, self.periodically)
- __blackjack__
- User
- Beiträge: 13931
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Nobima: `Tk` ist ein Fenster. Wenn Du zwei davon erstellst, dann hast Du zwei Fenster. Wobei es Zufall ist, dass das reibungslos funktioniert, denn `Tk` ist *das* Hauptfenster, davon darf es immer nur eines geben. Für zusätzliche Fenster ist `Toplevel` da.
Was heisst ”zur Verfügung haben”? Wenn Du kein zweites Fenster haben möchtest, dann wird aus dem Beispiel nicht so wirklich klar was Du eigentlich machen willst. Warum ist das denn überhaupt auf zwei Module aufgeteilt?
Was heisst ”zur Verfügung haben”? Wenn Du kein zweites Fenster haben möchtest, dann wird aus dem Beispiel nicht so wirklich klar was Du eigentlich machen willst. Warum ist das denn überhaupt auf zwei Module aufgeteilt?
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
Bis zu einer gewissen Länge des Programms, hast du die beste Übersicht, wenn alles in einer Datei steht.
Viel wichtiger ist eine fachliche Trennung. Funktionen, die die Datenbank abfragen, sollten nichts mit der GUI zu tun haben. Das Hauptfenster steuert die Nutzer-Interaktion, und damit auch wann die Datenbank abgefragt wird.
Viel wichtiger ist eine fachliche Trennung. Funktionen, die die Datenbank abfragen, sollten nichts mit der GUI zu tun haben. Das Hauptfenster steuert die Nutzer-Interaktion, und damit auch wann die Datenbank abgefragt wird.
- __blackjack__
- User
- Beiträge: 13931
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Nobima: Ergebnisse von Funktionen werden über den Rückgabewert kommuniziert. Genau so kommst Du doch auch an den Zufallswert den `random.randint()` intern erzeugt.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
Die allgemeinen Hinweise sind sicher sehr hilfreich, bringen mich aber nicht weiter. Mit einem entsprechenden Code-Schnipsel, der zeigt, wie die Rückgabe des Wertes aus der Modul-Klasse ins Hauptscript erfolgt, würde mir helfen.
Hallo,
kannst du das an Hand meines Beispiels nicht? Kann es sein, dass eventuell das Allgemeine Verständnis mit dem Umgang von Klassen und Funktionen noch fehlt?
Meinst du das so?
Grüße
Dennis
kannst du das an Hand meines Beispiels nicht? Kann es sein, dass eventuell das Allgemeine Verständnis mit dem Umgang von Klassen und Funktionen noch fehlt?
Meinst du das so?
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
from random import randint
class Sensor:
def __init__(self):
pass
@property
def temperature(self):
return randint(0, 30)
class TemperatureDisplay(tk.Frame):
def __init__(self, master, sensor):
tk.Frame.__init__(self, master)
tk.Label(self, text="Außentempertur:").grid(row=0, column=0)
self.outside_temperature = tk.Label(self, text="0 °C")
self.outside_temperature.grid(row=1, column=0)
self.start = tk.Button(self, text="Start", command=self.read_sensor)
self.start.grid(row=2, column=0)
self.sensor = sensor
def update_temperature(self):
self.outside_temperature.config(text=f"{self.sensor.temperature} °C")
def read_sensor(self):
self.update_temperature()
self.after(1000, self.read_sensor)
def main():
sensor = Sensor()
root = tk.Tk()
root.title("Temperaturübersicht")
app = TemperatureDisplay(root, sensor)
app.pack()
app.mainloop()
if __name__ == "__main__":
main()
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
- __blackjack__
- User
- Beiträge: 13931
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Nobima: Modul-Klasse und Hauptskript spielen dabei überhaupt keine Rolle. Funktionen und Rückgabewerte funktionieren überall gleich, egal in welchem Modul die Funktion definiert ist, und egal von wo aus die Funktion aufgerufen wird.
Die `randint()`-Funktion hast Du doch auch in aus einer Methode heraus aufgerufen und das Ergebnis dann in der Funktion dort verwendet, also ausgegeben. Genau so macht man das halt. Du hast da also schon ein selbst geschriebenes Beispiel was genau das macht was Du willst. Statt einer Funktion die eine Zufallszahl liefert aus einem anderen Modul zu verwenden, musst Du halt eine schreiben, die Deine Messwerte liefert, und die in dem ersten Modul verwenden, so wie Du das im zweiten Modul mit `randint()` machst.
Die `randint()`-Funktion hast Du doch auch in aus einer Methode heraus aufgerufen und das Ergebnis dann in der Funktion dort verwendet, also ausgegeben. Genau so macht man das halt. Du hast da also schon ein selbst geschriebenes Beispiel was genau das macht was Du willst. Statt einer Funktion die eine Zufallszahl liefert aus einem anderen Modul zu verwenden, musst Du halt eine schreiben, die Deine Messwerte liefert, und die in dem ersten Modul verwenden, so wie Du das im zweiten Modul mit `randint()` machst.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
- __blackjack__
- User
- Beiträge: 13931
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Wobei die `Sensor`-Klasse in dem Beispiel so natürlich nicht sinnvoll ist, weil es keine Klasse ist. Also jetzt bitte nicht eine Funktion sinnlos in eine Klasse stecken. Ist ja nicht Java. 
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
Beim Umschreiben des Codes habe ich mir schon gedacht, dass so eine Bemerkung kommen wird 
Wollte nur nicht mit irgendwelchen erfundenen Angaben in der __init__ verwirren.
Grüße
Dennis
Wollte nur nicht mit irgendwelchen erfundenen Angaben in der __init__ verwirren.
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
- __blackjack__
- User
- Beiträge: 13931
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Ja, das war mir schon klar, dass Du da ein Beispiel vereinfacht hast. Wollte nur sichergehen, dass das auch klar wird für jemanden für den Klassen noch neu sind. 
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware