Nach 5min Inaktiv Bild anzeigen

Fragen zu Tkinter.
BlackJack

@schnibli: Das war irgendwie zu erwarten. Wo sollte die Methode denn auch herkommen?
schnibli
User
Beiträge: 27
Registriert: Mittwoch 19. November 2014, 18:52

Ja eignetlich schon aber ich weis nicht wo oder wie ich dies machen muss.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Sowas wie ein self.root fehlt halt, für ein self.root.after(... ;)

Schau dir doch einfach mal Tk Beispiele an. Bei http://tkinter.unpythonic.net gibt es einiges an Code... (Keine Ahnung wie die Qualität davon ist)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi schnibli,
schnibli hat geschrieben:Hallo, ich kriege folgenden fehler bei:

Code: Alles auswählen

        self.after(self.last_action_time_poll_interval, self._last_action_time_checker)

Code: Alles auswählen

AttributeErrot: 'MainFrame' object has no attribute 'after'
hast Du meine Fragen überlesen oder nur ignoriert? Ich fragte, wo das tk.Tk aus den Klammern hinter 'class MainWindow' aus unserem Beispielcode geblieben ist.

Die dort angegebene Klasse nennt man Basisklasse. Ich gehe davon aus, dass Du Dich schon mit dem Python Klassensystem und Ableitungen beschäftigt hast?
Wenn vom Pythoninterpreter eine Methode in der aktuellen Klasse nicht gefunden wird, dann wird in ihren Basisklassen gesucht. '.after' ist eine Methode der Basisklasse tk.Tk und wenn Du die Basisklasse einfach weglässt, kann sie logischerweise nicht mehr gefunden werden. Aus welchem Grund hast Du die Basisklasse denn weggelassen?

Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
schnibli
User
Beiträge: 27
Registriert: Mittwoch 19. November 2014, 18:52

Ich weis nicht wo es hingekommen ist.
Ich habe jetzt mal ein Standard Programm genommen und versucht den Timer zu implementieren.

Code: Alles auswählen

import tkinter as tk
import time

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.last_action_time = 0
        self.last_action_time_poll_interval = 1000  # 1000 ms min. Zeit zwischen zwei Aufrufen
        self.last_action_delay = 5                    # 300 s, bevor die Methode self.handle_action aufgerufen wird
        self._last_action_time_checker()

    def say_hi(self):
        print("hi there, everyone!")

    def _last_action_time_checker(self):
        if self.last_action_time:
            if (time.time() - self.last_action_time) > self.last_action_delay:
                self.last_action_time = 0                # Sicherstellen, dass die Aktion nur einmal pro Ablauf ausgeführt wird
                self.handle_action()
        self.after(self.last_action_time_poll_interval, self._last_action_time_checker)
        print("1")
    def handle_action(self):
        print("2")
 
    def any_callback(self, event=None):
        self.last_action_time = time.time()           # setzt den Counter auf die aktuelle Zeit hoch -> Differenz = 0


root = tk.Tk()
app = Application(master=root)
app.mainloop()
print("3")
def _last_action_timer_checker(self) Funktioniert alle sekunden wird "1" ausgegeben, jedoch erscheint nie "2" das heist def hanle_action wird nicht aufgerufen
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@schnibli: und wann wird any_callback aufgerufen?
schnibli
User
Beiträge: 27
Registriert: Mittwoch 19. November 2014, 18:52

"any_callback" ist ja eigentlich um den Stand "zurückzusetzen".
Ich versuche nah bis nah diesen Code lauffähig zu machen, daher wollte ich zuerst, das dieser auslöst und anschließend die Rücksetzung.

Ahh lol okey jetzt habe ich verstanden ;) ansonsten wird die time nicht gesetzt
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

schnibli hat geschrieben:Ahh lol okey jetzt habe ich verstanden ;) ansonsten wird die time nicht gesetzt
Exakt, die Aktion sollte erst eine Zeit nach der letzten eigenen Aktion ausgeführt werden.
Bei nochmaligem Lesen war das aber gar nicht die Aufgabe. Das Bild sollte angezeigt werden, wenn 5 Minuten lang nicht geklickt wurde - unabhängig davon, ob schonmal geklickt wurde, oder nicht. In dem Fall kannst Du 'self.last_action_time' natürlich gleich mit 'time.time()' initialisieren.
Tut mir leid, ich habe mal wieder nicht richtig aufgepasst. :(
Diese Nachricht zersört sich in 5 Sekunden selbst ...
schnibli
User
Beiträge: 27
Registriert: Mittwoch 19. November 2014, 18:52

Es tut dir leid?
Das ist das kleinste Problem.
Ich hab es jetzt dank euch zum Laufen gekriegt, die ist ja wohl supper :)

Ich habe dies nun in mein Programm eingebaut:

Code: Alles auswählen

class timer(tk.Frame):
    def __init__(self, master=None):
        
        tk.Frame.__init__(self, master)
        self.last_action_time = 0
        self.last_action_time_poll_interval = 1000  # 1000 ms min. Zeit zwischen zwei Aufrufen
        self.last_action_delay = 5                  # 300 s, bevor die Methode self.handle_action aufgerufen wird
        self._last_action_time_checker()
        self.say_hi()

    def say_hi(self):
        self.last_action_time = time.time()

    def _last_action_time_checker(self):
        if self.last_action_time:
            if (time.time() - self.last_action_time) > self.last_action_delay:
                self.last_action_time = 0                # Sicherstellen, dass die Aktion nur einmal pro Ablauf ausgeführt wird
                self.handle_action()
        self.after(self.last_action_time_poll_interval, self._last_action_time_checker)
        print(time.time())
        #print(self.last_action_time)
        
    def handle_action(self):
        #print("12")
        Bildschirmschoner()
         
    def any_callback(self, event=None):
        self.last_action_time = time.time()           # setzt den Counter auf die aktuelle Zeit hoch -> Differenz = 0
        print("2")
Es Funktioniert auch
Nach genau 5 Sekunden (Testzeit da ich nicht immer 5min Warten möchte ;) )
soll ein neues Fenster aufgehen:

Code: Alles auswählen

class Bildschirmschoner(object):
    def __init__(self):
        self.root = tkinter.Tk()
        self.root.title("Example")
        app=FullScreenApp(self.root)
        
        self.text = tkinter.Text()
        self.text.pack(fill=tkinter.BOTH, expand=tkinter.YES)
 
        for event_name in event_map.values():
            self.root.bind("<%s>" % event_name, self._update_status)
 
    def _update_status(self, event):
        txt = event_map[int(event.type)]
        msg = "%s [ %sx%s ]\n" % (txt, event.x, event.y)
        self.text.insert(tkinter.INSERT, msg)
        self.text.see(tkinter.INSERT)
        print("status")
        self.root.destroy()
 
    def mainloop(self):
        self.root.mainloop()
(Hier sollen die Berührungen erkannt werden)--> Funktioniert auch.
Jedoch im Vollbildmodus erscheint es nicht im Vordergrund, sondern das alte Fenster bleibt im Vordergrund:

Code: Alles auswählen

class MainFrame():
    def __init__(self):
        
        
        self.root = tk.Tk()
        self.state=False
        app=FullScreenApp(self.root)
        app=timer(self.root)
 
       
        ##start_class_button = tk.Button(self.root, text="Öffnen", command=self.do_start_class, width=20)
        
     

        ##Kalender öffnen 
        self.kalender=PhotoImage(file='/home/pi/Desktop/praesentation/kalender.gif')
        self.kalender_menu_button = tk.Button(self.root, image=self.kalender, command=self.kalender_modus)

        ##Präsentation öffnen
        self.praesentation=PhotoImage(file='/home/pi/Desktop/praesentation/praesentations_modus.gif')
        self.praesentations_modus_button = tk.Button(self.root, image=self.praesentation, command=self.praesentation_modus)

        ##Präsentation öffnen
        self.radio=PhotoImage(file='/home/pi/Desktop/praesentation/radios.gif')
        self.radio_button = tk.Button(self.root, image=self.radio, command=self.radio_modus)

        ##Beenden
        exit_button = tk.Button(self.root, text="beenden", command=self.do_exit, width=20)
        
        ##start_class_button.pack()
        
        self.kalender_menu_button.pack()
        self.praesentations_modus_button.pack()
        self.radio_button.pack()
        exit_button.pack()
        self.root.mainloop()
    
    def do_exit(self):
        self.root.quit()
        self.root.destroy()
 
 
    def kalender_modus(self):
        if self.state==False:
            print ("starte Subfenster...")
            self.buttons = Kalender(tk.Toplevel())
            self.state=True
            
        else:
            print ("schließe Subfenster...")
            self.state=False

    def radio_modus(self):
        if self.state==False:
            print ("starte Subfenster...")
            self.buttons = Radio(tk.Toplevel())
         
            self.state=True
        else:
            print ("schließe Subfenster...")
            self.state=False

    def praesentation_modus(self):
        if self.state==False:
            print ("starte Subfenster...")
            self.buttons = Bilder(tk.Toplevel())
 
            self.state=True
        else:
            print ("schließe Subfenster...")
            self.state=False

            
myframe = MainFrame()
Antworten