如何在tkinter中使用按键闪烁按钮?

时间:2014-10-26 01:18:28

标签: python tkinter

我有一个tkinter按钮小部件,我想在按下按键时闪烁。密钥绑定到根窗口。我已尝试将按键绑定到按钮以及根窗口,将按钮状态设置为ACTIVE并设置按钮takefocus = 1,但按下按钮时按钮不会闪烁。该按钮非常适合展示,因为它没有被点击,但我还是希望它能够闪现。

root = Tk()
leftButton = Button(root, text="F", borderwidth=0)
root.bind("<KeyPress-F>", buttonPress1)
root.bind("<KeyPress-f>", buttonPress1)
leftButton.grid(row=3, column = 0)
leftButton.bind("<KeyPress-F>")
leftButton.bind("<KeyPress-f>")
leftButton.configure(state=ACTIVE)
leftButton.configure(takefocus=1)

2 个答案:

答案 0 :(得分:2)

(知道了)我会通过在按键上按下按钮来改变颜色,如下所示:

import tkinter as tk

r = tk.Tk()

l = tk.Label(text = 'press f to make button flash')
l.pack()

b = tk.Button(text = 'useless button')
b.config(bg = 'lightgrey')
b.pack()

def flash(event):
    b.config(bg = 'yellow')
    r.after(100, lambda: b.config(bg = 'lightgrey'))

r.bind("<KeyPress-f>", flash)

r.mainloop()

这使按钮变为黄色,持续十分之一秒,这就像我可以得到的闪光一样:)

我希望这可以帮助你。

答案 1 :(得分:0)

#  TkButtonFLASH.py                         # execfile( "TkButtonFLASH.py" )
#  
import Tkinter as tk
import tkMessageBox

class TestButtonFLASH():

    def FlashStep1(                         self, anEvent ):
        KeyHANDLER( anEvent )                                 # .DEBUG
        if self.LOCK_STEP1:                                   # .IF  .LOCK_STEP1
            return                                            #      .RET
            '''
            print "LOCK_STEP1: blocks further .bind() events ",
                  "from entering into an unfinished transaction ",
                  "state,\n            still in waiting <state> ",
                  "before .after() finishes the started ",
                  "transaction & UNLOCKs LOCK_STEP1"
            return                                            #      .RET after print
            '''
        self.LOCK_STEP1         = True                        # .SET .LOCK_STEP1
        self.PUSH_POP           = self.leftButton['bg']       # .PUSH current value in Class.attribute
        self.leftButton['bg']   = 'yellow'                    # .SET
        self.leftButton.after( 100, self.FlashStep2 )         # .SCHEDULE 100 [ms] self.FlashStep2()
        self.leftButton.update()                              # .UPD GUI

    def FlashStep2(                         self ):
        self.leftButton['bg']   = self.PUSH_POP               # .POP/.SET previous value from .attribute
        self.LOCK_STEP1         = False                       # .SET !LOCK_STEP1
        self.leftButton.update()                              # .UPD GUI

    def ExitPROCESS(                        self ):           # MVC-Controller-Part ..
        if tkMessageBox.askokcancel( "Quit GUI", "Do you really wish to quit?" ):
            self.master.destroy()
        pass

    def __init__(                           self, master ):   # MVC-setup { Model + Visual + Controller }
        # -------------------------------------------------------------- UI-state-var(s), not used so-far/anymore :)
        self.PUSH_POP            = ""
        self.LOCK_STEP1          = False                                # .SET !LOCK_STEP1
        # -------------------------------------------------------------- UI-construction ----------------------------------------------------------------
        self.master              = master
        self.master.title(      "Test TkButtonFLASH v0.0" )             # .title()
        self.master.geometry(   "400x400-50-50" )                       # .geometry
        #elf.master.iconbitmap()                                        # .iconbitmap
        self.master.protocol( 'WM_DELETE_WINDOW', self.ExitPROCESS )    # [X]-overide ---------------------------
        self.master.lift()                                              # raise window

        self.leftButton          = tk.Button( self.master, text = "F", borderwidth = 1, bg = "green" )
        self.leftButton.grid( row = 0, column = 0 )

        self.master.bind( "<KeyPress-F>", self.FlashStep1 )
        self.master.bind( "<KeyPress-f>", self.FlashStep1 )
        self.master.bind( "<KeyPress>",   KeyHANDLER )
        self.master.mainloop()

def KeyHANDLER( anEvent ):                                              # .DEBUG utility
    print "<Key>-event: ", anEvent.serial, anEvent.time, anEvent.char, anEvent.keysym, anEvent.keysym_num, str( anEvent.widget )

def main():
    root = tk.Tk()
    app  = TestButtonFLASH( root )

if __name__ == '__main__':
    main()

这种基于类的方法使用两步事务和类属性来存储和携带原始的 ['bg'] 值,以便在150 [ms]之后恢复闪光灯。

需要添加两步拆分事务的保护

可以看到按住键盘键一段时间(直到BIOS打字速率设置超时和自动重复功能开始触发................ ......像PKT这样的事件 - pulemyot-Kalashnikova-tankovyj:

<Key>-event:  1240 323533265 s s 115 .
<Key>-event:  1241 323533296 s s 115 .
<Key>-event:  1242 323533343 s s 115 .
<Key>-event:  1243 323533375 s s 115 .
<Key>-event:  1244 323533390 s s 115 .
<Key>-event:  1245 323533437 s s 115 .
<Key>-event:  1246 323533468 s s 115 .
<Key>-event:  1247 323533500 s s 115 .
<Key>-event:  1248 323533515 s s 115 .
<Key>-event:  1249 323533562 s s 115 .

从原始KeyHANDLER()输出中可以看出,事件发生率略微变化约15-50 [msec],这比两步Flash事务最短时间要快得多,所以会有出现更多交易 - &#34;开始&#34;在第一笔交易完成之前。

因此,添加了原始事务锁定以避免这种副作用。