Python Forum
Tkinter messagebox and using datetime/timedelta
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tkinter messagebox and using datetime/timedelta
#1
Hi all

I made this really simple program for myself to remind me to take some breaks.


It works great and all, although there is one behavior that I did not expect and although I don't mind it so much, i'd like to understand why it happens.

When the while loop is going and an interval variable is passed, the messagebox will come up. However, until I close the messagebox, it won't repeatedly come up multiple times. In fact I believe even the 'if' statement does not come into play again until I close that message box. My questions are:
  • Shouldn't multiple messageboxes be coming up based on the if statement? Wouldn't the loop constantly be going, meaning multiple boxes come up?
  • Does everything stop (including the loop) when the messagebox comes up?


import datetime as dt
from tkinter import *

def setInterval():
    interval = dt.timedelta(minutes = int(entry_1.get()))
    StartTime = dt.datetime.now()
    while True:
        if dt.datetime.now() == StartTime + interval:
            messagebox.showinfo('STRETCH TIME',message = "Please take a stretch break!") 
            StartTime = dt.datetime.now()
    
        
    

if  __name__ == "__main__":
    root = Tk()
    intervariable = IntVar()
    theLabel = Label(root,text="Enter time below in minutes (e.g 30)")
    theLabel.pack()
    entry_1 = Entry(root)
    entry_1.pack()  
    button_1 = Button(root,text="Set interval",command=setInterval)
    button_1.pack()
    root.mainloop()
Appreciate any assistance :)
Reply
#2
There are seven forms of message box. Each of these request some sort of input from the user before continuing with the current process.

I think it would be possible to create multiple messages if each were issued in a separate thread (ended when a response was received). This could, however cause some issues if allowed to run for an extended length of time without response to any of the messages. Perhaps a limit on how many are issued, which would require a notification from each thread when completed.
Reply
#3
The problem you are having is the while loop in "setInterval()" prevents "root.mainloop()" from running. If root.mainloop() doesn't run you program does not react to events like button presses. mainloop() can be the only forever loop in you tkinter app.
Reply
#4
Example of using the after method to do something after every second without blocking the GUI event loop.
import tkinter as tk
from tkinter import messagebox
import datetime as dt


class MainFrame(tk.Frame):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        theLabel = tk.Label(self, text="Enter time below in minutes (e.g 30)")
        theLabel.pack()
        self.entry_1 = tk.Entry(self)
        self.entry_1.pack()
        button_1 = tk.Button(self, text="Set interval",
                             command=self.set_alarm_time)
        button_1.pack()
        self.timenow_label = tk.Label(self)
        self.timenow_label.pack()
        self.alarm_time_label = tk.Label(self, text='Alarm time:')
        self.alarm_time_label.pack()
        self.pack()
        self.alarm_time = None
        self.timer()

    def set_alarm_time(self):
        try:
            interval = dt.timedelta(minutes=int(self.entry_1.get()))
        except ValueError:
            self.entry_1.delete(0, tk.END)
            messagebox.showinfo(
                'Entry error', message="Please enter an integer")
            return

        self.alarm_time = dt.datetime.now() + interval
        self.alarm_time_label['text'] = self.alarm_time.strftime(
            'Alarm time: %H:%M:%S')

    def timer(self):
        timenow = dt.datetime.now()
        self.timenow_label['text'] = timenow.strftime('Time now: %H:%M:%S')
        if self.alarm_time and timenow >= self.alarm_time:
            self.alarm_time = None
            self.alarm_time_label['text'] = 'Alarm time:'
            self.entry_1.delete(0, tk.END)
            messagebox.showinfo(
                'STRETCH TIME', message="Please take a stretch break!")

        self.after(1000, self.timer)


if __name__ == "__main__":
    app = tk.Tk()
    main_frame = MainFrame()
    app.mainloop()
Larz60+ likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] Sound from the tkinter.messagebox tedarencn 2 5,834 Jul-11-2020, 10:45 AM
Last Post: steve_shambles
  [Tkinter] Messagebox with playsound khandelwalbhanu 6 4,307 May-16-2020, 11:40 AM
Last Post: chesschaser
  [Tkinter] messagebox is not being executed please help erwinsiuda 2 2,242 Apr-02-2020, 01:56 AM
Last Post: Larz60+
  [Tkinter] passing data to messagebox kmusawi 0 1,779 Feb-18-2019, 01:51 AM
Last Post: kmusawi
  Adding timer on the Messagebox aniyanetworks 6 11,567 Feb-13-2019, 07:48 PM
Last Post: aniyanetworks
  [Tkinter] Button widget gets stuck from using tkinter.messagebox? Nwb 2 3,852 Jun-20-2018, 02:21 PM
Last Post: Nwb

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020