我正在使用一个旋转框来实时控制字体大小,以实现缩放效果。 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()
最佳答案
我对两种类型的旋转框都使用了类似的解决方案,但实现方式有所不同,因为它们不使用相同的事件。这个想法是
创建带有_increment_lock
属性的Spinbox类,当Spinbox递增且延迟设置回True
后,该属性设置为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()
关于python - 如何限制窗口小部件生成的事件数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58906587/