如何限制小部件生成的事件数

发布于 2021-01-29 17:26:05

我正在使用旋转框实时控制字体大小,以实现缩放效果。Spinbox小部件可以生成许多事件。只要按住键盘上的方向键或单击并按住方向小部件箭头图标之一,事件就会由旋转框生成。
问题是我要参加许多活动,这使缩放效果挂起。我已经安装了一个演示,使用两个不同的Spinbox(tk.Spinbox和ttk.Spinbox)对此进行了演示。使用tk.Spinbox,您可以很好地使用“
repeatdelay and
repeatinterval”来限制速率,这确实有效,只有当您单击Spinbox中的箭头按钮之一时,它才起作用。如果您按向上或向下键,则“
repeatdelay and repeatinterval”无效。至于ttk.Spinbox,它除了参数“ repeatdelay and
repeatinterval”之外,所以对它没有影响。如何限制两种类型的旋转框的重复率?

import tkinter as tk
import tkinter.ttk as ttk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.rowconfigure(990, weight=1)
        self.columnconfigure(0, weight=1)
        self.title('Timed Events Demo')
        self.geometry('420x200+20+20')

        tk_spn = tk.Spinbox(
            self,
            value=0,
            from_=0, to=1000,
            repeatdelay=500,
            repeatinterval=500,
            values=list(range(0, 1000))
        )
        tk_spn.grid(row=0, pady=5)

        tk_spn = ttk.Spinbox(
            self,
            from_=0, to=1000,
            value=0,
            values=list(range(0, 1000))
        )
        tk_spn.grid(row=1, pady=5)

        self.cnt = 0

        def test(e):
            print(self.cnt, e)

        tk_spn.bind('<<Increment>>', test)


def main():
    app = App()
    app.mainloop()


if __name__ == '__main__':
    main()
关注者
0
被浏览
47
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    我为两种类型的旋转框使用了类似的解决方案,但是实现方式略有不同,因为它们不使用相同的事件。想法是创建一个Spinbox类,其_increment_lock属性设置为TrueSpinbox递增时和延迟设置为时的False。然后,使旋转框增加的事件绑定到_increment_lock在实际执行增加之前检查的方法。减量原理相同。

    对于tk.Spinbox,我使用了<Up>和的绑定来<Down>实现上述解决方案,而我使用了<<Increment>>和的绑定<<Decrement>>

    这是代码:

    import tkinter as tk
    import tkinter.ttk as ttk
    
    
    class MySpinbox(tk.Spinbox):
        def __init__(self, master=None, delay=500, **kwargs):
            kwargs.setdefault('repeatdelay', delay)
            kwargs.setdefault('repeatinterval', delay)
            tk.Spinbox.__init__(self, master, **kwargs)
            self.delay = delay  # repeatdelay in ms
            self.bind('<Up>', self._on_increment)
            self.bind('<Down>', self._on_decrement)
            self._increment_lock = False
            self._decrement_lock = False
    
        def _unlock_increment(self):
            self._increment_lock = False
    
        def _on_increment(self, event):
            if self._increment_lock:
                return "break"  # stop the increment
            else:
                self._increment_lock = True
                self.after(self.delay, self._unlock_increment)
    
        def _unlock_decrement(self):
            self._decrement_lock = False
    
        def _on_decrement(self, event):
            if self._decrement_lock:
                return "break"  # stop the increment
            else:
                self._decrement_lock = True
                self.after(self.delay, self._unlock_decrement)
    
    
    class MyTtkSpinbox(ttk.Spinbox):
        def __init__(self, master=None, delay=500, **kwargs):
            ttk.Spinbox.__init__(self, master, **kwargs)
            self.delay = delay  # repeatdelay in ms
            self.bind('<<Increment>>', self._on_increment)
            self.bind('<<Decrement>>', self._on_decrement)
            self._increment_lock = False
            self._decrement_lock = False
    
        def _unlock_increment(self):
            self._increment_lock = False
    
        def _on_increment(self, event):
            if self._increment_lock:
                return "break"  # stop the increment
            else:
                # generate a virtual event corresponding to when the spinbox
                # is actually incremented
                self.event_generate('<<ActualIncrement>>')
                self._increment_lock = True
                self.after(self.delay, self._unlock_increment)
    
        def _unlock_decrement(self):
            self._decrement_lock = False
    
        def _on_decrement(self, event):
            if self._decrement_lock:
                return "break"  # stop the increment
            else:
                # generate a virtual event corresponding to when the spinbox
                # is actually decremented
                self.event_generate('<<ActualDecrement>>')
                self._decrement_lock = True
                self.after(self.delay, self._unlock_decrement)
    
    
    class App(tk.Tk):
        def __init__(self):
            super().__init__()
            self.rowconfigure(990, weight=1)
            self.columnconfigure(0, weight=1)
            self.title('Timed Events Demo')
            self.geometry('420x200+20+20')
    
            tk_spn1 = MySpinbox(self, value=0, values=list(range(0, 1000)))
            tk_spn1.grid(row=0, pady=5)
    
            tk_spn2 = MyTtkSpinbox(self, from_=0, to=1000)
            tk_spn2.grid(row=1, pady=5)
    
            def test(e):
                print(e)
    
            tk_spn2.bind('<<ActualIncrement>>', test)
    
    
    if __name__ == '__main__':
        app = App()
        app.mainloop()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看