2

i'm writing python script and in it i have users GUI with button of delete account. After the user press the delete account button there is a popup messagebox (i use tkinter messagebox but other options is good as well) that ask him for Approval for the task. I would like to add option to make a some seconds pause that the user will must wait few seconds bedore clicking OK. If you know a way for Realize this possibility (not Necessarily tkinter) i really like to know it. Thanks for all helpers.

Joker
  • 21
  • 2
  • 2
    ***pause is after the messagebox poped out and before his click.***: You have to use your own [Dialog Window](http://effbot.org/tkinterbook/tkinter-dialog-windows.htm) where your `Button` [`state=DISABLED`](http://effbot.org/tkinterbook/button.htm#Tkinter.Button.config-method) and [to use after method](https://stackoverflow.com/a/25753719/7414759) to enable it delayed. – stovfl May 16 '20 at 18:56
  • I don't think tkinter has that feature. May be the only way is that the @stovfl has explained above. – Ayush Raj May 16 '20 at 19:02
  • 1
    Hi Joker, if the answer solves your issue you can [accept](https://stackoverflow.com/help/someone-answers) it. Feel free let me know if you have any concern. – Rita Han May 27 '20 at 09:14

1 Answers1

1

By using the base class Dialog of tkinter.simpledialog module we can create any custom dialog boxes.

enter image description here

Here's how I did it.

from tkinter import *
import tkinter.simpledialog as sd


class WaitAlert(sd.Dialog):
    """An alert which will wait for a given time before user can interact.

    Args:
        parent: Takes the parent window instance.
        title (str): Main heading of the alert.
        message (str): Information to display.
        pause (int): Time till inactive. (in seconds)
        show_timer (boolean): Shows countdown."""

    def __init__(self, parent, title=None, message=None, pause=None, show_timer=False):
        self.message = message or ''
        self.pause = pause
        self.show_timer = show_timer
        super().__init__(parent, title=title)

    def body(self, master):
        # For macOS, we can use the below command to achieve a window similar to an alert.
        # Comment the below line if you are on windows.
        self.tk.call("::tk::unsupported::MacWindowStyle", "style", self._w, "moveableAlert")
        Label(master, text=self.message).pack()

    def _timer(self, count, b1, b2):
        "Timer function."
        if count > 0:
            if self.show_timer: b1['text'] = str(count)
            self.after(1000, self._timer, count-1, b1, b2)
        else:
            if self.show_timer: b1['text'] = "OK"
            b1['state'] = 'normal'
            b2['state'] = 'normal'

    def buttonbox(self):
        box = Frame(self)
        b1 = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE, state='disabled')
        b1.pack(side=LEFT, padx=5, pady=5)
        b2 = Button(box, text="Cancel", width=10, command=self.cancel, state='disabled')
        b2.pack(side=LEFT, padx=5, pady=5)
        if self.pause is not None: 
            self._timer(self.pause, b1, b2)
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.cancel)
        box.pack()

    def apply(self):
        self.result = True
        return super().apply()


Now you can either save this class in a separate python file and use it by importing it. For example, I saved it as tkDialog.py and then import it in your main file (from tkDialog import WaitAlert) or you can keep it at the beginning of your main file.

Here is a small example on how to use it.

from tkinter import *
from tkDialog import WaitAlert

root = Tk()
# `wm_withdraw()` will hide the window from the screen.
root.wm_withdraw()
popup = WaitAlert(parent=root,
              title='Alert!', 
              message='Do you want to delete this account?', 
              pause=5,  # pauses for 5 secs.
              show_timer=True) # show countdown.
print(popup.result)   # get the result.
# If the user clicks "OK" the result will return "True" else return "None".

Hope this helped you.

Saad
  • 3,340
  • 2
  • 10
  • 32