I am making a custom messagebox widget.My work is under process.But i cant make it as real as Tkinter Messagebox in terms of functionality. Here is my Code.
from tkinter import *
from tkinter.ttk import Style,Frame as fp
class messagebox():
def __init__(self,parent):
self.parent = parent
#image in base 64 encoded format to make a round corner window with ttk frame
borderImageData='''
iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACplBMVEUy6qsy6qsy6qsy6qsy6qsy6qsy6qsy6qsy6qsy6qsy6qsw66sq76wm8awl8qwk8qwk8qwq76ww66sy6qsy6qsy6qso8Kwd960Z+q0Y+q0Y+q0Y+q0Y+q0Z+q0d960p8Kwy6qsy6qsy6qsy6qsm8qwZ/a8X/q8X/a8Y/a8X/q8Z/a8m860y6qsy6qsy6qsr76wc6aMgwIkgvoggvoggvoggvogd4J0r76wy6qsy6qsx6qsg+K4eyI4yPDkzNjUzNjUzNDQjqXsg+K4x6qsy6qsy6qst7asa/K8fx44yOTczMjMzMzMzMTIjp3oa/K8t7asy6qsy6qsp8KwY/a8fx44yOTczMzMzMzMzMjIjp3oY/a8p8Kwy6qsy6qsl8qwX/a8fx44jp3oX/q8l8qwy6qsy6qsy6qsj86wX/a8X/q8j86wy6qsy6qsy6qsi9KwX/q8i9Kwy6qsy6qsi9Kwi9Kwi9Kwi9Kwi9Kwi9Kwy6qsy6qsi9KwX/a8X/q8i9Kwy6qsy6qsy6qsk86wX/a8X/q8k86wy6qsy6qsm8awX/a8fx44jp3oX/q8m8awy6qsy6qsr7qwY/a8fx44jp3oY/a8r7qwy6qsy6qsv7Ksc+q8fxo0zNjUzMDEzMDE0LjAjpnkc+68v66sy6qsy6qsl9K0d1JYralUsZlIsZlIsZVEgvIcl9K0y6qsy6qsw7Ksf9KsY9KkZ9KkZ9KkZ9KkY9Kkf86sw7Ksy6qsy6qsu7asf9q0Y+q0Y+60Y+60Y+q0Y+q0Y+60Y+q0f9q0u7asy6qsy6qsw66sn8Kwg9awc960b+K0b+K0b+K0b+K0c960g9awn8Kww66sy6qsy6qsy6qsx6qsw66su7Ksu7Ksu7Ksu7Ksw66sx6qsy6qsy6qsy6qsy6qv///+KamaqAAAAAWJLR0ThXwjPpgAAAAd0SU1FB+QJEgMqIg5MPcQAAAGdSURBVFjDY2AYPoCRiZmFlUjAwsbEjqqbg5OLm4eXj1+AKMDPxysoJMzJgaRfRFRMXEJSSppIICUjKyevoIgwQUlZRVVNXYMEoK6ppa2jCzdAT9/A0MiYJGBiamZuAdNvaWVtY2tnTxpwcHRydoEa4Orm7uHp5U0a8PH18w+AGhAYFBwSGhZOGoiIjIqOgRoQGxefQLoBiUnJKRD9qWnpGeQYkJmVnQo2ICc3jywD8gsKcyAGFBWTZ0BJEcyAUvIMKB01YNSAUQNGDRg1YNSAUQNGDcBpQBl5BpTBDSgnz4AKqAGVVdU15BhQW1dfCTagobGpmRwDWlrbGiANxfaOzi7SDeju6e2DtlT7J0ycRLoBk6dMnQY1YPqMmbNmz5lLGpg3f8HCRVADKhcvWbps+QrSwMpVq9ekwjoMa9et37BxE0lg85at29bCeyzbd+zctXvP3n37iQT79h44eOjwke1I3bajx46fOHnq9BmiwOmz585fuHgJpd+3/fKVq9eu37hJFLhx6/adu+wcDGjgHuP9B0SC+4z3GIYRAAABmvVGkLvY1QAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMC0wOS0xOFQwMzo0MjozNC0wNDowMAx3N+gAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjAtMDktMThUMDM6NDI6MzQtMDQ6MDB9Ko9UAAAAAElFTkSuQmCC
'''
__button_image='''
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAABmJLR0QA/wD/AP+gvaeTAAABfUlEQVRYhe2XvW7CMBCAz3EgtRkoCDGgItq+AltFN96hvAxIdOmzMFV9gHZo+w6dCqLqxMBPRZMSEsyAhI1Bug7gZPA3WefhPp0vjo/U63VIE07SAjpWCMMKYVghDCuE4e6HipFojcLGbFn9i9nq+CkDB77O6Hve7ZW9sUu0XaL9OpqTZWcY8FgcX2QPn5JujT0XMmqQVioV1eah72dNyAAAZAQ0J8s+owNGt0HZQ8VIdIaBXsETQwA6w6AQyRpIodYoNHNSGrlY3I0WB4Qa09C8zYbbWbRdS6GLxQm+qP9RVVJLIZ6YD6itkrqL0QphWCEMK4RhhTCsEIYVwpBCPjX8WpT8Kqml0LeXWLXU1HL1lj8wEpnhVUkthXplL5FTm1PSK3sHhMYu6daY4Ve+ALi/5FNlXNyZywaM9hm9+YnMjGZzStrXuZfznVbZEdo4PZWyoQN8BTwWmROY+Q58MvpYyrav+Aen2q4+SidOii/GlGCFMKwQhhXCSJ3QGuU2Yh1mj+sEAAAAAElFTkSuQmCC
'''
self.__ShowInfo='''
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
'''
self.ShowInfo_icon=PhotoImage(data=self.__ShowInfo,master=self.parent)
self.ButtonImage=PhotoImage( data=__button_image,master=self.parent)
self.borderImage = PhotoImage( data=borderImageData,master=self.parent)
#Style creation for ttk frame
self.TP_style=Style()
self.TP_style.element_create("RoundedMB",
"image", self.borderImage,
border=14, sticky="nsew")
self.TP_style.layout("RoundedMB",
[("RoundedMB", {"sticky": "nsew"})])
def showinfo(self,title="ShowInfo",msg="Hello,There!",icon='ShowInfo'):
self.app = Toplevel()
self.app.geometry("550x200")
#end of position management
self.parent.wm_attributes("-disabled",True)#Disables the state of parent till destroy
self.app.wm_attributes("-topmost",True)
self.app.wm_attributes("-transparentcolor", "#32EAAB")#border color transparent
self.app.overrideredirect(True)#Borderless window
self.app.focus_set()#Focus set
#Window will cover with "self.frame_one" for every widget
self.frame_one = fp(self.app, style="RoundedMB", padding=8)
self.frame_one.pack(fill='both', expand=True)
toolbar = Frame(self.frame_one, height=25, bg='red')
toolbar.place(x=-1, y=0,width=self.width-14)
self.set_icon=self.ShowInfo_icon
#Label to show an icon of information like default messagebox
L=Label(self.frame_one,image=self.set_icon,bg='#333333')
L.pack(side='left')
self.msg=msg
def procced():
self.parent.wm_attributes("-disabled",False)
self.app.destroy()
self.value=True
#Button to press OK
YButton = Button(self.frame_one,image=self.ButtonImage,text='OK',compound='cente',command=lambda:procced(),bg="#333333",bd=0,highlightthickness=0,font="lucida 9 bold",fg='white',activebackground='#333333')
YButton.pack(side='bottom')
#message to print in message widget
message=Message(self.frame_one,text=self.msg,bg='#333333',
fg='white',font='lucida 10 bold',width=360).place(x=65,y=27)
#Title bar like default windows title bar
title_bar=Label(toolbar,text=title,bg='red',fg='white',font='lucida 12 bold')
title_bar.pack()
def destroy(event):
self.parent.wm_attributes("-disabled",False) #configure normal state to parent
self.app.destroy()
self.parent.wait_window(self.app) #parent will wait untill this toplevel destroy
return self.value #retutn value True as output like default messagebox
if __name__ == "__main__":
root = Tk()
root.geometry("800x600+300+5")
menu = messagebox(root)
def call():
h=menu.showinfo('Warning','i am alone,help me!!!')
print(h)
Button(root,text='open',command=call).pack(side='bottom')
root.mainloop()
I want to know how to work like normal messagebox ?,i mean flashing while focus out, come along with parent window(means not to hide behind) when parent has focus in/out.I know flashing is not possible due to overredirect flag,but if anyone give me idea about proper event binding to achieve the flashing effect,then i just change 2/3 colors to my toolbar in a loop. If you go for parent.winfo_children state disable method then it does not work for me cause I have some labels in bind events. Any help will be appriciated. Thank You!! EDIT: I have deleted the extra lines used for centering position of screen and mouse draging.Remaining are essential
So I did another toplevel over the root and made it transparent.. this color you can change how you like and its still responsive after deactivate the root.
import tkinter as tk
root=tk.Tk()
def top():
top = tk.Toplevel()
top.overrideredirect(1)
top2 = tk.Toplevel()
root.update_idletasks()
top2.overrideredirect(1)
top2.config(bg='red')
top2.attributes('-alpha', 0.11)
x,y = root.winfo_rootx(), root.winfo_rooty()
width, height = root.winfo_width(),root.winfo_height()
top2.geometry("%dx%d+%d+%d" % (width,height,x,y))
root.wm_attributes("-disabled",True)
top2.bind('<Button-1>', lambda e ,top=top2:flash(top))
top.bind('<Escape>', lambda e: top.destroy())
top.bind('<Destroy>', lambda e: [top2.destroy(),root.wm_attributes("-disabled",False)]))
def flash(top):
print('hi')
top.after(50,lambda: top.configure(bg='blue'))
top.after(120,lambda: top.configure(bg='red'))
top.after(170,lambda: top.configure(bg='blue'))
top.after(240,lambda: top.configure(bg='red'))
b = tk.Button(root, command=top)
b.pack()
root.mainloop()
If you have any questions, let me know.