“确认”用户cli

2024-04-26 06:31:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我看到当你按下电视遥控器上的按钮时,它不会立即进入频道,过了一段时间它就会进入频道,但如果你在某个时间段内按下按钮,它就不会进入频道。你知道吗

在tkInter中有没有一种方法可以做到这一点,如果用户在一段时间内(在本例中是两秒钟)单击按钮,除非用户没有单击按钮,否则函数不会执行。你知道吗

为了澄清,我想将命令执行延迟2秒,这样如果用户再次按下同一按钮,您就可以再次取消它。你知道吗


Tags: 方法函数用户命令tkinter频道按钮电视
2条回答

您可以随时断开按钮和操作,并在它们之间放置一个可以取消的计时器。Tkinter提供了^{} method来延迟调用回调。你也可以使用一个线程来给你更多的控制。你知道吗

下面的实现可以用作任何tkInter元素的回调;它需要一个延迟(以秒为浮点数)和一个回调来调用延迟,而不需要再次单击。在调用DelayedCancellable()和取消时,会立即调用另外两个可选回调:

import time
from threading import Thread, Event

class DelayedCancellable:
    def __init__(self, delay, after_delay, invoked=None, cancelled=None):
        super().__init__()
        self._after_delay = after_delay
        self._on_invoked = invoked
        self._on_cancelled = cancelled
        self._delay = delay
        self._thread = None
        self._cancelled = Event()

    def __call__(self):
        if self._thread is not None and self._thread.is_alive():
            self._cancelled.set()
        else:
            if self._on_invoked is not None:
                self._on_invoked()
            self._thread = Thread(target=self._delayed_execution)
            self._thread.start()

    def _delayed_execution(self):
        try:
            if self._cancelled.wait(self._delay):
                # we got cancelled, exit
                if self._on_cancelled is not None:
                    self._on_cancelled()
                return
            self._after_delay()
        finally:
            self._thread = None
            self._cancelled.clear()

使用它时,以秒为单位传递一个延迟作为浮点数,回调:

from tkinter import Button

def callback():
    print("Hello, world!")

b = Button(
    master,
    text="Click me!",
    command=DelayedCancellable(2.0, callback)
)

上述按钮将导致Hello, world!打印,除非您在2秒内再次单击该按钮。你知道吗

可以使用额外的invokedcancelled操作来更新UI,以便为用户提供更多的反馈:

from tkinter import Button, RAISED, SUNKEN

def button_invoked():
    b.config(relief=SUNKEN)

def button_cancelled():
    b.config(relief=RAISED)

def callback():
    button_cancelled()  # clear state
    print("Hello, world!")

b = Button(
    master,
    text="Click me!",
    command=DelayedCancellable(2.0, callback, button_invoked, button_cancelled)
)

一种不同于玛蒂恩·皮尔斯的方法。我用了.after来安排一个事件在2秒后发生,而不是单独的线程。你知道吗

单击一次按钮将导致在2秒后调用ConfirmedAction函数。在2秒钟的窗口内再次单击按钮,将取消计时器。你知道吗

import tkinter as tk

def ConfirmedAction():
    print("Doing something")

class ConfirmButton(tk.Button):
    def __init__(self,master,**kw):
        self.confirmcommand = kw.pop('confirm',None)
        super(ConfirmButton, self).__init__(master, **kw)
        self.timer = None
        self['command'] = self._clicked
    def _clicked(self):
        if not self.timer:
            self.timer = self.after(2000,self._doAction)
        else:
            self.after_cancel(self.timer)
            self.timer = None
            print("Action Cancelled")
    def _doAction(self):
        self.confirmcommand()
        self.timer = None

root = tk.Tk()
btn1 = ConfirmButton(root,text="Hello",confirm=ConfirmedAction)
btn1.grid()
root.mainloop()

相关问题 更多 >

    热门问题