Seite 1 von 1
Fenster laufend aktualisieren
Verfasst: Montag 23. Juni 2014, 15:14
von Üpsilon
Hallo mal wieder.
Kann mir jemand sagen, wie ich mache, dass WÄHREND mein GUI-Programm läuft, ständig die gleichen Anweisungen ausgeführt werden? Einfach eine Schleife ins Programm reinbasteln scheint ja nicht so ganz die empfohlene Strategie zu sein und funktioniert bei mir auch gar nicht.
Wenn daraus jez nicht ersichtlich geworden ist, was ich meine, kann ich gerne noch meinen Quellcode posten, aber ich wollte hier nicht rumspämmen.
Danke und Lg Y.
Edit (23. 6. 16:53) : Thread-Titel geändert
Re: Irgendeinen Befehl STÄNDIG ausführen
Verfasst: Montag 23. Juni 2014, 15:22
von EyDu
Einfach einen Thread starten. Sei aber vorsichtig, ein Thread darf nicht einfach Elemente der GUI verändern, das geht nicht gut aus. Zum Thema Threads und GUIs gibt es hier im Forum aber genug, einfach mal ein wenig suchen.
Re: Irgendeinen Befehl STÄNDIG ausführen
Verfasst: Montag 23. Juni 2014, 15:52
von Üpsilon
Erstmal danke für die schnelle Antwort.
EyDu hat geschrieben:ein Thread darf nicht einfach Elemente der GUI verändern.
Menno. Ich will aber!!!
Nein, ich meinte eher, dass laufend das Fenster aktualisiert wird. Ich glaube, ich ändere mal den Titel dieses Themas.
Re: Fenster laufend aktualisieren
Verfasst: Montag 23. Juni 2014, 16:00
von EyDu
Was genau willst du denn machen, deine neue Beschreibung ist ja noch viel allgemeiner geworden. Prinzipiell kommen mehrere Ansätze in Frage. Wie sieht denn dein ganz konkretes Problem aus?
Re: Fenster laufend aktualisieren
Verfasst: Montag 23. Juni 2014, 17:12
von Üpsilon
Ist inzwischen relativ egal, weil ich es jetzt hinbekommen habe. ^^
Mein Programm sollte mit einem numerischen Verfahren Pi annähern und die Zwischenergebnisse in einer GUI anzeigen, und das nach jedem Näherungsschritt. Und die Berechnung soll man auch pausieren können.
Ich hab das jetzt so gemacht, dass mein Eventhandler sich nach jedem Schritt rekursiv selbst aufruft. Aber egal, danke.
Re: Fenster laufend aktualisieren
Verfasst: Montag 23. Juni 2014, 17:20
von BlackJack
@Üpsilon: Ich hoffe mal der Eventhandler macht das nicht tatsächlich rekursiv, denn Schleifen als Rekursionen ausdrücken funktioniert in Python nicht wirklich, wie eigentlich in allen Programmiersprachen nicht in denen die Sprachdefinition keine „tail call optimization” garantiert.
Re: Fenster laufend aktualisieren
Verfasst: Montag 23. Juni 2014, 17:28
von Üpsilon
BlackJack hat geschrieben:@Üpsilon: Ich hoffe mal der Eventhandler macht das nicht tatsächlich rekursiv, denn Schleifen als Rekursionen ausdrücken funktioniert in Python nicht wirklich...
Nee, da ist der schon nach 100 Durchläufen abgestürzt. Ich benutze für die Rekursion
fenster.after(), wobei
fenster ein
tkinter.Tk() ist.
Re: Fenster laufend aktualisieren
Verfasst: Montag 23. Juni 2014, 17:57
von Üpsilon
Falls es jemanden interessiert, ich klatsch hier mal den Quellcode rein. In der Methode pi_naehern wird zufällig ein Punkt generiert, dann wird mit dem Pythagoras geguckt, ob der im gedachten Viertel-Kreis drin ist, und dann wird mit Hilfe der "Trefferquote" überlegt, wie groß der Kreis denn ungefähr ist und wie groß Pi folglich sein muss. Der Rest ist für die GUI zuständig.
Code: Alles auswählen
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import tkinter as tk
from random import random
class Pi_Rechner:
def __init__(self, update_schritt=100, wartezeit=500):
self.punkte_gesetzt = 0
self.punkte_im_kreis = 0
self.laeuft = False
self.update_schritt = update_schritt
self.wartezeit = wartezeit
self.init_fenster()
def init_fenster(self):
self.fenster = tk.Tk()
self.fenster.geometry("400x150")
self.fenster.title("Pi nähern")
self.gesetzt_label = tk.Label(self.fenster)
self.im_kreis_label = tk.Label(self.fenster)
self.pi_label = tk.Label(self.fenster)
for label in (self.gesetzt_label, self.im_kreis_label, self.pi_label):
label.config(font="Arial 14")
label.pack()
self.startstop_button = tk.Button(self.fenster, text="Start", command=self.umschalten)
self.startstop_button.pack()
def umschalten(self):
self.laeuft = not self.laeuft
button_text = "Pause" if self.laeuft else "Weiter"
self.startstop_button.configure(text=button_text)
if self.laeuft:
self.durchlauf()
def pi_naehern(self):
self.punkte_gesetzt += 1
x, y = random(), random()
abstand = (x**2 + y**2) ** 0.5
if abstand <= 1:
self.punkte_im_kreis += 1
def gui_aktualisieren(self):
self.gesetzt_label.configure(text = "Punkte gesetzt: %i" %self.punkte_gesetzt)
self.im_kreis_label.configure(text = "Punkte im Viertelkreis: %i" %self.punkte_im_kreis)
self.pi_label.configure(text = "π = 4*%i/%i = %f"
%(self.punkte_im_kreis, self.punkte_gesetzt,
4 * self.punkte_im_kreis / self.punkte_gesetzt))
def durchlauf(self):
self.pi_naehern()
if self.punkte_gesetzt % self.update_schritt == 0:
self.gui_aktualisieren()
self.fenster.after(self.wartezeit, self.durchlauf)
elif self.laeuft:
self.fenster.after(0, self.durchlauf)
pi_rechner = Pi_Rechner(10000, 1)
Ich weiß, es ist nicht der Event-Handler, der sich rekursiv aufruft. Aber so was ähnliches! ^^
Edit (19:10) : kleinen Fehler in umschalten() korrigiert.
Re: Fenster laufend aktualisieren
Verfasst: Montag 23. Juni 2014, 22:16
von BlackJack
@Üpsilon: Das Programm beendet sich bei mir sofort wieder. Da fehlt ein Aufruf der Tk-Hauptschleife damit das Programm dauerhaft läuft.