Programm hängt sich auf

Fragen zu Tkinter.
Antworten
semper27
User
Beiträge: 14
Registriert: Freitag 24. April 2015, 16:14

Hallo,
ich wollte ein Programm schreiben, das so lange Hi! auf der Konsole ausgibt, bis man auf den Stop Button klickt. Leider funktioniert es nicht, das Programm hängt sich auf, wenn ich auf Stop klicke. Hier ist der Code:

Code: Alles auswählen

from Tkinter import *

class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()
    def createWidgets(self):
        self.ok = Button(self)
        self.ok["text"] = "starten"
        self.ok["command"] = self.start
        self.ok["fg"]   = "blue"
        self.ok.pack({"side": "left"})
        self.QUIT = Button(self)
        self.QUIT["text"] = "Stop"
        self.QUIT["command"] = self.stop
        self.QUIT.pack({"side": "left"})
   
        def stop(self):
               self.stop = True
         def start(self):
                self.stop = False
        
        while self.stop == False:
            print ("Hi !")
root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()
Könnt ihr mir helfen, das Programm besser zu schreiben?
BlackJack

@semper27: Mal davon abgesehen dass das Programm so wie es dort steht nicht einmal kompiliert, kann man in GUI-Anwendungen keine länger laufenden Schleifen schreiben. Das muss man entweder so schreiben das eine Funktion/Methode die einem Schleifendurchlauf entspricht regelmässig per `after()`- oder `after_idle()`-Methode ausgeführt wird, oder man startet einen separaten Thread. Da gleich eine Warnung vorweg: Die GUI darf nur aus dem Thread heraus verändert werden in dem die `mainloop()` läuft.

Was Dir noch Probleme machen wird ist das Du versuchst das Attribut `stop` an eine Methode *und* einen Wert zu binden.

Das mit dem Sternchen-Import solltest Du lassen und `Tkinter` besser als `tk` importieren: ``import Tkinter as tk``, und dann die Objekte aus dem Modul über den abgekürzten Modulnamen ansprechen.
BlackJack

Code: Alles auswählen

#!/usr/bin/env python
from __future__ import absolute_import, division, print_function
import time
import Tkinter as tk


class MainFrame(tk.Frame):

    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.start_button = tk.Button(self, text='Start', command=self.start)
        self.start_button.pack(side=tk.LEFT)
        self.stop_button = tk.Button(
            self, text='Stop', command=self.stop, state=tk.DISABLED
        )
        self.stop_button.pack(side=tk.LEFT)
        self.current_id = None

    def _print_hi(self):
        print('Hi!', time.time())
        self.current_id = self.after_idle(self._print_hi)

    def start(self):
        assert self.current_id is None
        self.start_button['state'] = tk.DISABLED
        self.stop_button['state'] = tk.NORMAL
        self._print_hi()

    def stop(self):
        assert self.current_id is not None
        self.start_button['state'] = tk.NORMAL
        self.stop_button['state'] = tk.DISABLED
        self.after_cancel(self.current_id)
        self.current_id = None


def main():
    root = tk.Tk()
    main_frame = MainFrame(root)
    main_frame.pack()
    root.mainloop()


if __name__ == '__main__':
    main()
semper27
User
Beiträge: 14
Registriert: Freitag 24. April 2015, 16:14

Vielen Dank BlackJack, so funktionert es :D
Antworten