如何在python-tkinter中制作自定义消息框



我正在制作一个自定义的消息框小部件。我的工作正在进行中。但就功能而言,我无法使它像Tkinter Messagebox那样真实。这是我的密码。

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() 

我想知道如何像普通的收件箱一样工作?,我的意思是,当焦点在外时闪烁,当父窗口有焦点在内/外时与父窗口一起出现(意味着不要躲在后面(。我知道闪烁是不可能的,因为overreddirect标志,但如果有人告诉我如何正确绑定事件以实现闪烁效果,那么我只需循环更改工具栏的2/3颜色。如果你选择parent.winfo_children state disable方法,那么它对我不起作用,因为我在绑定事件中有一些标签。任何帮助都会得到通知。非常感谢。编辑:我已经删除了用于屏幕居中位置和鼠标拖动的额外行。剩余部分是必不可少的

所以我在根上做了另一个顶层,并使其透明。。这种颜色你可以改变你喜欢的方式,并且在停用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()

如果你有任何问题,请告诉我。

最新更新