当前位置:首页 » tkinter » 正文

tkinter创建一个新窗体Topleve

Topleve组件创建一个新窗体

Toplevel这个组件可用于新建一个窗体,这个新建的窗体跟我们Tk()根窗体在外表上完全一样,事实上,Tk()根窗体上的属性方法也完全可以照搬到Toplevel新建的窗体中。

新建一个窗体,语法: Toplevel(父组件)

from tkinter import *
 
root=Tk() # 创建主窗口
root.title('主窗口')  # 设置主窗口标题
root.geometry('250x100+888+400') # 设置主窗口大小和位置
 
top1=Toplevel(root) # 创建新窗口
top1.title('新建窗口') # 设置新窗口的标题
top1.geometry('250x100+888+556') # 设置新窗口的大小和位置
 
la1=Label(root,text='root上的标签') # 在主窗口创建一个标签
la1.pack()
la2=Label(top1,text='top1上的标签') # 在新窗口创建一个标签,注意父组件为top1
la2.pack()
 
root.mainloop()

上面代码先创建主窗口root,接下来的代码要创建一个新窗口,那么这个新窗口的父组件就是主窗口root,接下来的代码,是分别在主窗口和新窗口创建1个标签。

运行结果:

                                              1.JPG  2.JPG

如果不是我特意把这2个窗口设置不同的标题,标签也设置不同的文字显示,否则真搞不清楚,那个窗口是新建的。

在新窗口创建标签的方法也完全一样,唯一不同的是新建窗口创建标签,填写的父组件是root,其它的方面完全相同。

由于新窗口的父组件是root,所以,当你关闭新窗口,root窗口还存在,如果你直接关闭root,那新窗口因为父组件的关闭而一同关闭。

Topleve组件来模拟一个自定义的对话框

前面说了,以前说的窗体的属性,方法等知识都可以用于Toplevel窗体,下面我就用Toplevel模拟一个输入整数的简单对话框来复习一下窗体的相关知识。

代码如下:

from tkinter import *
from tkinter import messagebox
 
def popup():
    def ok():
        try:
            var.set(int(en1.get())) # 在主窗口的标签上显示
            # int(en1.get()) 由系统去判断是否为int数据
            top1.destroy() # 退出
        except: # 系统判断不是整数
            messagebox.showwarning("警告:","数据非法,非整数")
            
    def cancel():
        var.set(None) 
        top1.destroy() # 退出弹出窗口
 
    top1=Toplevel(root) # 创建新窗口
    top1.title('录入') # 设置新窗口的标题
    top1.geometry('200x100+888+556') # 设置新窗口的大小和位置
 
    la1=Label(top1,text='请输入整数:') # 注意父组件是top1
    la1.pack(padx=10,pady=5,anchor=W)
    
    en1=Entry(top1) # 注意父组件是top1
    en1.pack(padx=10,fill=X)
    en1.insert(END,'98') # 如果希望有默认的数值,就加上这句代码
 
    fr1=Frame(top1) # 创建fr1框架,用于2个按钮的横向排列
    fr1.pack(pady=5,anchor=CENTER,fill=X)
 
    but1=Button(fr1,text="确定",command=ok) # 注意:父组件是fr1
    but1.pack(side=LEFT,padx=(10,5),fill=X,expand=True)
     # 用fill=X,expand=True让系统去决定按钮的宽度
 
    but2=Button(fr1,text="取消",command=cancel)  # 注意:父组件是fr1
    but2.pack(side=RIGHT,padx=(5,10),fill=X,expand=True)
     # 用fill=X,expand=True让系统去决定按钮的宽度
 
root=Tk() # 创建主窗口
root.title('主窗口')  # 设置主窗口标题
root.geometry('250x100+888+400') # 设置主窗口大小和位置
    
var=IntVar() # 创建整型变量,绑定标签0,用于显示弹出窗体返回的整数
la0=Label(root,font=('黑体',24,'bold'),textvariable=var) # 绑定变量var
la0.pack()
but1=Button(root,text=" 弹出 ",command=popup) # 点按钮弹出对话框
but1.pack()
 
root.mainloop()


运行结果如下:

        3.JPG

点击弹出按钮后,弹出新窗体:

        7.JPG

如果输入的不是整数,点确定,会出现警告信息:

        8.JPG

新窗体在父窗体居中显示,置顶显示的代码

但上面的代码,我觉得还有必要完善:     丶丌皛

1.窗体可以手动调整大小,不妥。解决代码:

top1.resizable(False,False) # 不可调节窗体大小

2.窗体还有最大化,最小化按钮按钮可以操作,解决代码:

top1.attributes("-toolwindow", 1) # 无最大化,最小化的标题栏

3.弹出窗体时,新窗体的文本框没有得到焦点,解决代码:

en1.focus_force()

4.弹出要置顶在主窗体root之上才好,解决办法:

top1.transient(root) # 窗口只置顶root窗体之上

5.不关闭弹出窗体,还可以回到主窗体去操作,不妥,解决办法:

top1.grab_set() # 转化模式

6.希望弹出窗体的位置相对于主窗口是居中。

top1.update() # 刷新后,下面代码才能得到正确的宽和高尺寸
a,b=top1.winfo_width,top1.winfo_height() # 得到弹出窗体的宽和高
c=root.winfo_x()+((root.winfo_width()-a)/2) # 左边距=主窗口左边距+[(主窗口宽-弹出窗体宽)/2]
d=root.winfo_y()+((root.winfo_height()-b)/2) # 上边距=主窗口上边距+[(主窗口高-弹出窗体高)/2]
top1.geometry('%dx%d+%d+%d' % (a,b,c,d)) # 弹出窗体相对主窗体居中显示

7.弹窗从新位置移到居中显示的位置,有闪动,解决办法:

先让弹窗隐藏起来,代码:

top1.withdraw() # 弹窗暂时隐藏起来

最后,在弹窗的组件都已经创建好了,窗体也移到新的居中位置,再显示窗口。代码:

top1.deiconify() # 窗口再显现

 

以下是改进后的全部代码:      源码作者网站 wb98.com

from tkinter import *
from tkinter import messagebox
 
def popup():
    def ok():
        try:
            var.set(int(en1.get())) # 在主窗口的标签上显示
            # int(en1.get()) 由系统去判断是否为int数据
            top1.destroy() # 退出
        except: # 系统判断不是整数
            messagebox.showwarning("警告:","数据非法,非整数")
            
    def cancel():
        var.set(None) 
        top1.destroy() # 退出弹出窗口
 
    top1=Toplevel(root) # 创建新窗口
    top1.title('录入') # 设置新窗口的标题
    top1.geometry('200x100+888+556') # 设置新窗口的大小和位置
    top1.withdraw() # 弹窗暂时隐藏起来
 
    la1=Label(top1,text='请输入整数:') # 注意父组件是top1
    la1.pack(padx=10,pady=5,anchor=W)
    
    en1=Entry(top1) # 注意父组件是top1
    en1.pack(padx=10,fill=X)
    en1.insert(END,'98') # 如果希望有默认的数值,就加上这句代码
 
    fr1=Frame(top1) # 创建fr1框架,用于2个按钮的横向排列
    fr1.pack(pady=5,anchor=CENTER,fill=X)
 
    but1=Button(fr1,text="确定",command=ok) # 注意:父组件是fr1
    but1.pack(side=LEFT,padx=(10,5),fill=X,expand=True)
     # 用fill=X,expand=True让系统去决定按钮的宽度
 
    but2=Button(fr1,text="取消",command=cancel)  # 注意:父组件是fr1
    but2.pack(side=RIGHT,padx=(5,10),fill=X,expand=True)
     # 用fill=X,expand=True让系统去决定按钮的宽度
 
    top1.update() # 刷新后,下面代码才能得到正确的宽和高尺寸
    a,b=top1.winfo_width(),top1.winfo_height() # 得到弹出窗体的宽和高
    c=root.winfo_x()+((root.winfo_width()-a)/2) # 左边距=主窗口左边距+[(主窗口宽-弹出窗体宽)/2]
    d=root.winfo_y()+((root.winfo_height()-b)/2) # 上边距=主窗口上边距+[(主窗口高-弹出窗体高)/2]
    top1.geometry('%dx%d+%d+%d' % (a,b,c,d)) # 弹出窗体相对主窗体居中显示
 
    top1.attributes("-toolwindow", 1) # 无最大化,最小化
    top1.attributes('-topmost',1) # 窗口置顶其它窗体之上
    top1.transient(root) # 窗口只置顶root之上
    top1.resizable(False,False) # 不可调节窗体大小
    top1.grab_set() # 转化模式,不关闭弹窗就不能进行别的操作
    en1.focus_force()  # 文本框得到焦点
    top1.deiconify() # 窗口再显现 源码网站 wb86.com
 
root=Tk() # 创建主窗口
root.title('主窗口')  # 设置主窗口标题
root.geometry('350x200+888+400') # 设置主窗口大小和位置
    
var=IntVar() # 创建整型变量,绑定标签0,用于显示弹出窗体返回的整数
la0=Label(root,font=('黑体',24,'bold'),textvariable=var) # 绑定变量var
la0.pack()
but1=Button(root,text=" 弹出 ",command=popup) # 点按钮弹出对话框
but1.pack()
 
root.mainloop()

运行后结果:

           9.JPG

以上代码在win10系统测试成功。

我觉得新窗体在父组件居中显示的代码还是很有实用价值,大家可以收藏此文,也许以后有用。


下一篇文章我来讲讲事件和绑定。


来源:济亨网

本文链接:http://wb98.com/post/314.html

    << 上一篇 下一篇 >>

    湘公网安备 43011102000514号 - 湘ICP备08100508号