首页 文章

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

提问于
浏览
1

我有一个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 回答

  • 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()
    

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

    我希望这能够帮到你 .

  • 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事务最小时间要快得多,因此会出现更多事务 - "starts"第一笔交易完成 .

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

相关问题