2016-04-09 4 views
0

Meine Anforderung ich ein Programm entwickle, in dem ich umgehen Raum und KeyPress-Raum Event zeitbasierte Ereignis zu behandeln.Tkinter pack_forget() und pack() Ausgabe auf Schlüsselrelease Ereignisse

Was ich mache, ist, dass beim Start des Programms ein Fenster geöffnet wird, um ein Zeitintervall anzuzeigen, sagen wir "5", das 5 Sekunden darstellt. Sobald die Zeit verstrichen ist (5 Sekunden), verschwindet der Text "5".

Nach dass der Benutzer erforderlich ist Raum Taste zu drücken, wenn der Benutzer drücken Raum Taste die gleiche Anzahl, bis der Benutzer angezeigt wird nicht loslassen Raum Schlüssel.

Ich habe 2 Sekunden Lücke gegeben nächstes Intervall zu zeigen (wenn Benutzer den Raum) und in diesem Intervall die Zahl sollte nicht angezeigt werden, die in früheren eingestellten Zeitintervall Raum Ereignis erscheinen wurden.

Problem Statement: Das Problem, das ich bin vor ist, dass ich es geschafft haben, Nummer (Text) auf Tastendruck angezeigt werden, aber wenn ich Loslassen der Taste, Zeitintervall nicht für 2 Sekunden verschwindet.

Hier ist mein Code:

from tkinter import Label, Tk 
import time 

times = [3, 4, 5] 
loop = 0 

class Demo: 
    def __init__(self, master): 
     global times, loop 
     self.parent = master 
     self.lbl = Label(master, text=times[loop]) 
     master.after(times[loop]*1000, self.hideLabelAfterSomeTime) 
     master.bind("<space>", self.hideLabel) 
     master.bind("<KeyRelease-space>", self.showLabel) 
     print('called', loop) 
     self.lbl.pack() 

    def hideLabel(self, event): 
     global loop, times 
     self.lbl.config(text=times[loop]) 
     self.lbl.pack() 

    def showLabel(self, event): 
     global loop 
     self.lbl.pack_forget() 
     time.sleep(2) 
     loop += 1 
     Demo(self.parent) 

    def hideLabelAfterSomeTime(self): 
     self.lbl.config(text= '') 

master = Tk() 
app = Demo(master) 
master.geometry("400x300+400+200") 
master.mainloop() 
+0

Es ist sehr unklar, was dieses Ding ... tun sollten, so ist es nicht leicht, Sie beheben zu helfen .. Es gibt auch einen Fehler nach ein paar Klicks auf der Leinwand: 'Listenindex außerhalb des Bereichs '......... Vielleicht möchten Sie die Zustände erklären, die Ihr System durchläuft, und vielleicht wird Ihr Fehler angezeigt, wenn Sie TU das. :) –

+0

Während der Benutzer drücken, sollte ein Feld angezeigt werden und wenn der Benutzer verlässt, sollte die Box verschwinden und das nächste Ereignis sollte auftreten und erneut dieselbe Operation wiederholen, bis die Schleife beendet ist. Bitte ignorieren Sie den Indexfehler für eine Weile. – Sahadev

Antwort

0

Sie scheinen eine „Spalte“ im Weg gefunden zu haben, Python mit der Tk Hauptschleife in Wechselwirkung tritt. Zumindest auf meinem System (Python 2.7, Fedora 22, x86_64) hat keiner der Vorgänge in showLabel() irgendwelche Auswirkungen auf den Bildschirm, bis die Funktion (einschließlich time.sleep (2)) abgeschlossen ist.

Wenn Sie den Code wie folgt für die Fehlerbehebung ändern, denke ich, dass Sie sehen können, was ich meine.

def hideLabel(self, event): 
    global loop, times 
#  self.lbl.config(text=times[loop]) 
    self.lbl.config(bg = "red") 
    self.lbl.pack() 

def showLabel(self, event): 
    global loop 
#  self.lbl.pack_forget() 
    self.lbl.config(fg = "blue") 
    time.sleep(2) 
    loop += 1 
    Demo(self.parent) 

def hideLabelAfterSomeTime(self): 
#  self.lbl.config(text= '') 
    self.lbl.config(bg = "green") 

Das zweite Etikett erscheint jetzt unterhalb des ersten. Das erste Etikett bekommt einen blauen Vordergrund, aber nicht den Tastendruck, wie wir es erwarten würden. Es wird anscheinend nur erhalten, wenn die Funktion zurückgibt, nach time.sleep().

Ich behaupte nicht, dies vollständig zu verstehen - jemand, der ein tiefgehendes Verständnis von Python und Tk hat, könnte dies erklären. Eine Problemumgehung für dieses bestimmte Programm besteht darin, update_idletasks() hinzuzufügen. Dies (Warnung: schlampige Terminologie voraus) zwingt die Tk-Hauptschleife, ausstehende Ereignisse sofort zu verarbeiten.

Auf meinem System, das das erste Etikett blau vor time.sleep() gemacht wurde. Ich habe darüber hinaus nicht experimentiert. ps. showLabel() verbirgt das Label und hideLabel() zeigt es?

EDIT: Der folgende kleine Mod des ursprünglichen geposteten Code funktioniert auf meinem System fast so, wie ich es erwarten würde. Ich bin nicht 100% sicher, was es zu tun ist. Aber das aktuelle Etikett verschwindet, wenn ich auf die Leertaste tippe, und das nächste Etikett erscheint 2 Sekunden später, nur um eine variable Zeit danach ausgeblendet zu werden.

Das einzige Rätsel, das ich fand, war, dass mein System im Grunde verrückt wurde, als ich versuchte, die Leertaste für mehr als 2 Sekunden gedrückt zu halten.Es stellte sich heraus, dass das Schlüssel-Auto-Repeat auf meinem System auftrat und mir Dutzende von Tastenanschlägen gab und Dutzende von Subscript-Fehlern außerhalb des Bereichs verursachte. Ich gab an diesem Punkt auf, so dass ich immer noch nicht weiß, wie sich das Programm verhält, wenn ein einzelnes Leerzeichen gegeben wird und 3 Sekunden später ein einzelnes Leerzeichen folgt.

from Tkinter import Label, Tk 
import time 

times = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] 
loop = 0 

class Demo: 
    def __init__(self, master): 
     global times, loop 
     self.parent = master 
     self.lbl = Label(master, text=times[loop]) 
     master.after(times[loop]*1000, self.hideLabelAfterSomeTime) 
     master.bind("<space>", self.hideLabel) 
     master.bind("<KeyRelease-space>", self.showLabel) 
     master.bind("<h>", self.showLabel) 
     print('called', loop) 
     self.lbl.pack() 
     for child in master.children: print child 

    def hideLabel(self, event): 
     global loop, times 
     self.lbl.config(text=times[loop]) 
     self.lbl.pack() 

    def showLabel(self, event): 
     global loop 
     self.lbl.pack_forget() 
     master.update_idletasks() 
     time.sleep(2) 
     loop += 1 
     Demo(self.parent) 

    def hideLabelAfterSomeTime(self): 
     self.lbl.config(text= '') 
     self.lbl.config(bg = "green") 

master = Tk() 
app = Demo(master) 
master.geometry("400x300+400+200") 
master.mainloop() 

Wenn die pack_forget keine Auswirkungen auf Ihrem System auch mit dem update_idletasks(), würde ich erraten, dass die Tk Hauptschleife mehr plattformabhängig ist als weithin bekannt.

+0

master.update_idletasks() funktioniert nicht – Sahadev

+0

Tut mir leid, das zu hören. Ich werde versuchen, einen anderen Blick Dienstagabend (GMT -6) zu werfen. –

+0

Scheint mehr oder weniger wie erwartet auf meinem System zu funktionieren. Es kann einige Unterschiede zwischen Plattformen geben - weiß ich nicht. Hmm. Ich lese gerade jetzt deine Erklärung nach dem ersten Kommentar von dem, was du sehen willst. Es wird auf meinem System niemals so funktionieren, bis/bis ich die automatische Schlüsselwiederholung deaktiviere. Entschuldigung - keine einfache Möglichkeit für mich, es zu testen. –

1

Hier go..Please Sie lassen Sie mich wissen, wenn Sie weitere Frage haben -

from tkinter import Label, Tk 
import time 

times = [3, 4, 5] 
loop = 0 

class Demo: 
    def __init__(self, master): 
     global times, loop 
     self.parent = master 
     self.lbl = Label(master, text=times[loop]) 
     master.after(times[loop]*1000, self.hideLabelAfterSomeTime) 
     master.bind("<space>", self.hideLabel) 

    master.bind("<KeyRelease-space>", self.showLabel) 
    print('called', loop) 
    self.lbl.pack() 

def hideLabel(self, event): 
    global loop, times 
    self.lbl.config(text=times[loop]) 
    self.lbl.pack() 

def showLabel(self, event): 

    global loop 
    self.lbl.pack_forget() 
    self.parent.update() 
    time.sleep(2) 
    loop += 1 
    Demo(self.parent) 

def hideLabelAfterSomeTime(self): 
    self.lbl.config(text= '') 

master = Tk() 
app = Demo(master) 
master.geometry("400x300+400+200") 
master.mainloop() 
+0

Vielen Dank Herr. Es hat mein Problem gelöst. Schätze deine Bemühungen. – Sahadev

Verwandte Themen