tkinter内嵌对话框

引言

说起对话框,它在程序应用界面中扮演着一个举足轻重的角色,通过对话框,可以更好地与使用者进行交互或者是信息提示,同时还能够减少应用界面本身的位置占用,在界面开发中很有用处。

但是要面对一个显示问题,有时需要对话框频繁弹出,以此来处理各种交互任务。可对于使用者而言,一会一个对话框弹出来,打扰对电脑的正常使用,是很影响对一个应用的感受的,这会使使用效果大大降低。

那么怎么解决这个问题,就需要用到内嵌对话框,使对话框显示在应用窗口中。


tkinter的对话框

自带对话框

众所周知,在tkinter中,输入框在simpledialog中,当使用这个输入对话框后,会弹出一个输入窗口。如果使用得多了,就会频繁弹出这种输入窗口,让人难免有些厌倦。那么现在,我们开始以输入对话框为例子,开始研究内嵌对话框。

构思

布局

和tkinter自带的输入对话框一样,我们的对话框也需要一个输入框(Entry)接受输入内容,然后通过按钮(Button)返回输入内容。

结构

此外,内嵌输入框还要做到一个功能——如果过对话框没有关闭,程序不能继续执行。也就是说,当对话框出现时,程序不能够再自己运行,要获得输入内容后才能够继续运行。

相信很多人(特别是刚入手tkinter的)看到这就很为难。因为,目前没有任何资料详细说明tkinter的对话框是怎么做到的,除非自己去研究simpledialog的源码。不过,我现在告诉大家,tkinter根本没有原生对话框(文件对话框除外),我们看到的simpledialog都是当年的Python开发大神们码出来的(此处应怀有感激心)。在这篇文章,我不打算详细分析simpledialog的源码,因为我也没有完全看懂。但是我们可以依据其中的基本思路,创造出新的输入对话框。

解决方案

为了完成tkinter的内嵌输入对话框,我们需要用到一个重要函数:wait_window(window)。这个函数存在于每一个tkinter窗口和组件。而且,tkinter中的输入框就是以这个为基础构建的。

这个函数的作用:暂停界面程序,直到被指定的组件被销毁或者是删除。

不要因为这个函数的字面意思而误解其参数的含义。window不只是tkinter窗口(toplevel/tk),也可以是组件(widget)


创造内嵌输入框

界面布局

这个很随意,因为只是例子:

root=Tk()
#...省略主窗口布局代码
def askstring(master,text):
    #主体框架
    frame=tk.Frame(master,bg='black',cursor='arrow',highlightthickness=3)
    #文本提示/说明
    label=tk.Label(frame,bg='black',fg='white',text=text)
    label.pack(side='top',fill='x',pady=10)
    #输入框
    entry=tk.Entry(frame,bg='white',fg='black',font=self['font'],relief='flat')
    entry.insert(0,word)
    entry.pack(side='top',fill='x',pady=10)
    #确认按钮
    button=ttk.Button(frame,text='确认')
    button.pack(side='top',fill='x')
    #内嵌输入对话框
    frame.place(x=0,y=0,width=self.winfo_width())
    #暂停程序
    master.wait_window(frame)

def test():
    a=askstring(root)
    print(a)
root.after(1000,test)
root.mainloop()

返回输入内容

因为我们使用了wait_window使界面暂停,所有当按钮被单击,或者是在输入框按下回车时,我们将输入的结果作为主窗口的一个属性,然后再删除内嵌输入框,返回这个值:

def askstring(master,text):
    #...
    #输入框
    entry=tk.Entry(frame,bg='white',fg='black',font=self['font'],relief='flat')
    entry.insert(0,word)
    entry.bind('<Return>',lambda event:over_askstring(master,frame,entry))
    entry.pack(side='top',fill='x',pady=10)
    #确认按钮
    button=ttk.Button(frame,text='确认',command=lambda:over_askstring(master,frame,entry))
    button.pack(side='top',fill='x')
    #内嵌输入对话框
    #...
    return master.askstring_result
def over_askstring(master,frame,entry):
    master.askstring_result=entry.get()
    frame.destroy()

完整代码例子

root=Tk()
#...省略主窗口布局代码
def askstring(master,text):
    #主体框架
    frame=tk.Frame(master,bg='black',cursor='arrow',highlightthickness=3)
    #文本提示/说明
    label=tk.Label(frame,bg='black',fg='white',text=text)
    label.pack(side='top',fill='x',pady=10)
    #输入框
    entry=tk.Entry(frame,bg='white',fg='black',font=self['font'],relief='flat')
    entry.insert(0,word)
    entry.bind('<Return>',lambda event:over_askstring(master,frame,entry))
    entry.pack(side='top',fill='x',pady=10)
    #确认按钮
    button=ttk.Button(frame,text='确认',command=lambda:over_askstring(master,frame,entry))
    button.pack(side='top',fill='x')
    #内嵌输入对话框
    frame.place(x=0,y=0,width=self.winfo_width())
    #暂停程序
    master.wait_window(frame)
    return master.askstring_result
def over_askstring(master,frame,entry):
    master.askstring_result=entry.get()
    frame.destroy()

def test():
    a=askstring(root)
    print(a)
root.after(1000,test)
root.mainloop()

在TinEngine中的效果

初版

在这里插入图片描述

TinEngine专栏

使用TinUI绘制

在这里插入图片描述
在这里插入图片描述
TinUI专栏


结语

这是在tkinter中的一个小创意,其界面布局在这篇文章中只是简单说明一下,还可以继续优化。本篇文章只提供思路。

☀tkinter创新☀

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值