如何在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',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',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() 

我想知道如何像普通的消息框一样工作,我的意思是聚焦时会闪烁,当父母有焦点在/聚焦时会伴随着父窗口(意味着不要藏在后面)。我知道由于过度重定向标志,但是如果有人给我有关适当的事件绑定以实现闪烁效果的想法,那么我只需循环更改工具栏的2/3颜色即可。 如果您选择parent.winfo_children状态禁用方法,那么它对我不起作用,因为我在绑定事件中有一些标签。 任何帮助将被申请。 谢谢!! 编辑: 我已经删除了用于屏幕居中和鼠标拖动居中的多余行。其余是必不可少的

解决方法

所以我对根进行了另一个顶层处理,并使之透明。.此颜色可以更改您喜欢的颜色,并且在禁用根后仍可以响应。

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

如果您有任何疑问,请告诉我。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...