0

I wanted to create a non-blocking message window with Tkinter. This in order to display a wait message, when another function is waiting for a reply. Once the reply is received the window can be closed automatically. I managed to find some info on the web and I made the following:

import tkinter as tk
import threading
import time

class Show_Azure_Message(threading.Thread):
    def __init__(self, message):
        self.thread = threading.Thread.__init__(self)
        self.message = message
        self.start()

    @staticmethod
    def callback():
        return

    def destroy(self):
        self.root.quit()

    #run will be called from self.start()
    def run(self):
        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.callback)
        self.t2 = tk.Text(self.root, height=10, borderwidth=0, wrap=tk.WORD)
        self.t2.insert(1.0, self.message)
        self.t2.grid(padx=5,row=2)
        self.t2.config(state=tk.DISABLED)
        self.root.mainloop()

App = Show_Azure_Message('Hello')
for i in range(0,2):
    print(i)
    time.sleep(1)

App.destroy()

This runs fine when I execute this as main script, but when I want to run another gui application with Tkinter right after i get the following error RuntimeError: main thread is not in main loop

Also when I run another piece of code after the App.destroy(). Then the App window doesn't close end the application keeps running.

root = tk.Tk()
label = tk.Label(root, text='Hello2')
label.pack()
root.mainloop()

So probably I am doing something wrong but I cannot find out what the problem is. Next to that I don't have much experience with Python Threads hence maybe I am missing something trivial over here.

regards, Geert

Grard
  • 61
  • 2
  • 5

1 Answers1

0

I think, if you really want to do it that way (look in the comment section of your post) you should use a Toplevel window instead since they don't need a mainloop which is making things way more easy in my eyes.

That's some kind of how I would do it if I would have to:

from tkinter import *
import threading
import time

class Show_Azure_Message(Toplevel):
    def __init__(self,master,message):
        Toplevel.__init__(self,master) #master have to be Toplevel, Tk or subclass of Tk/Toplevel
        self.title('')
        self.attributes('WM_DELETE_WINDOW',self.callback)
        self.resizable(False,False)
        Label(self,text=message,font='-size 25').pack(fill=BOTH,expand=True)
        self.geometry('250x50+%i+%i'%((self.winfo_screenwidth()-250)//2,(self.winfo_screenheight()-50)//2))

    def callback(self): pass

BasicApp=Tk()
App = Show_Azure_Message(BasicApp,'Hello')
for i in range(0,2):
    print(i)
    time.sleep(1)

App.destroy()
Nummer_42O
  • 334
  • 2
  • 16