精华内容
下载资源
问答
  • Python之tkinter中文教程,图形界面, Python进阶,Python爬虫基础
  • Tkinter教程

    2016-02-16 15:31:29
    非常详细的python图形界面组件开发教程,以代码的形式解析讲解,且所有代码都可直接运行,非常容易上手。 这系列教程完全以代码的形式来写的,目标是:读者看代码和注释就可以理解代码的意思。但这里的读者需要具备...
  • 基本概念GUI - Graphical User Interface. 中文叫图形用户接口。...tkinter 是python自带的模块,在安装python的同时,tkinter模块就已经在系统里了。只需import导入,即可使用。tkinter模块并没有网...

    基本概念

    GUI - Graphical User Interface. 中文叫图形用户接口。图像用户接口可以看做为人与计算机之间的沟通媒介。

    如果想为自己写的程序做一个易于操作的界面,那么,tkinter应该是最容易上手的图形接口开发工具。

    tkinter 是python自带的模块,在安装python的同时,tkinter模块就已经在系统里了。只需import导入,即可使用。tkinter模块并没有网上说的那么差,只是官方编写的tkinter的文档很差劲。之后的一段时间,我会将tkinter模块的使用做一个详细的介绍。

    导入tkinter模块

    from tkinter import * 或者是 import tkinter as tk

    这是两种最常见的导入写法。

    from X import * 和 import X 的区别

    在导入python 模块的时候,很多时候我们都面临上述两种导入的选择。下面我将说明这两种方法的区别。

    import X

    import X 意味着创建了一个模块 X的引用。假设模块X里有一个函数方法 func(),如果想调用func,就需要使用完整的路径,例如 X.func();

    from X import *

    from X import * 意味着对模块X里的所有对象创建了引用。此时,如果想调用func,只需要使用func()即可。同时,由于你并没有创建X的引用,你将无法通过X.func()调用func方法。

    举个例子,模块X相当于姓氏,模块X里的对象相当于名。如果一个班两个 ’天天‘,一个叫陶天天,一个叫欧天天。那么,老师就需要加上姓去区分两个’天天‘。但是,如果班里只有一个孩子叫’天天‘,就只需要喊’天天‘就好。

    导入tkinter模块之后,可以使用TkVersion去查看tkinter模块的版本。

    import tkinter as tkprint(tk.TkVersion)Out[2]: 8.6

    创建窗口

    tkinter中的Tk() 方法可以创建一个根窗口,之后添加的控件将会被放进这个创建的窗口里。

    import tkinter as tkwindow = tk.Tk()window.mainloop()
    47030041e6be7bc2690687871618da09.png

    创建的窗口,取名window

    window.mainloop() 会启动创建的window GUI。

    窗口建立好,就需要进行一些相关的设置。比如窗口标题,图标,大小,底色等等。

    添加图标

    默认的图标是一片树叶,如上图左上角。自己建的窗口,自然想换上漂亮、大气的图标。tkinter提供了iconbitmap 方法来更换图标。如果想使用下图作为图标,我们只需要如下设置。

    208e0ec7263a72fecf468d925f06d4aa.png

    图标

    import tkinter as tkwindow = tk.Tk()window.iconbitmap('palm-tree-icon.ico')window.mainloop()

    'palm-tree-icon.ico' 是图标存储的路径,如果图标在程序所在的文件夹里,可以直接调用。不然就得使用完整的路径。

    6d7923c4407242d6a55a2d6b90190e8d.png

    图标更改后的窗口

    设置标题

    默认的窗口标题是左上角的tk,通过title()可以设置窗口的标题。

    import tkinter as tkwindow = tk.Tk()window.title('逃学联盟')window.iconbitmap('palm-tree-icon.ico')window.mainloop()
    a513737983ff78a5af961e19be675952.png

    标题更改后的窗口

    设置背景颜色

    使用configure()设置背景颜色,window.configure(bg='#008CBA')

    import tkinter as tkwindow = tk.Tk()window.title('逃学联盟')window.configure(bg='#008CBA')window.iconbitmap('palm-tree-icon.ico')window.mainloop()
    04fd3de39ce034b48cbc0e468d13b9c3.png

    背景色设置后的窗口

    设置窗口大小和屏幕的相对位置

    geometry()可以用来设置初始窗口的大小以及窗口于屏幕的相对位置。注意,代码中的x不是乘法,是字母xy的x。具体方法如下:

    .geometry("窗口宽 x 窗口高 + 屏幕左边框相对距离 + 屏幕上边框相对距离")。

    import tkinter as tkwindow = tk.Tk()window.title('逃学联盟')window.configure(bg='#008CBA')window.geometry("500x100+300+300")window.iconbitmap('palm-tree-icon.ico')window.mainloop()

    上述代码创建了一个500 * 100 px大小的窗口,窗口左上角坐标是(300,300)。

    f690f5c618cec62737fe958fb3c7c1bc.png

    图片来源网络

    如果需要将窗口放在屏幕的正中,可以通过一些简单的计算和geometry()方法。

    通过.winfo_screenwidth() 和 .winfo_screenheight() 方法可以得到屏幕的宽和高。如果我们需要将窗口放在屏幕正中,窗口的左边框距离屏幕的左边框为 (屏幕宽 - 窗口宽)/ 2

    import tkinter as tkwindow = tk.Tk()window.title('逃学联盟')window.configure(bg='#008CBA')window_width = 500window_height = 100screen_width = window.winfo_screenwidth()screen_height = window.winfo_screenheight()x = int((screen_width - window_width)/2)y = int((screen_height - window_height)/2)window.geometry(f"{window_width}x{window_height}+{x}+{y}")window.iconbitmap('palm-tree-icon.ico')window.mainloop()

    设置窗口的最小的宽高,最大的宽高,全屏显示和窗口是否可以拖拽大小

    .resizable(True, True)方法设置窗口的宽和长是否可以拖拽调整大小;

    .minsize(宽, 高)方法设置窗口的最小宽高

    .maxsize(宽, 高)方法设置窗口的最大宽高

    .state('zoomed')方法设置窗口全屏显示

    .maxsize(宽, 高)方法 和 .state('zoomed')方法不要同时使用。

    import tkinter as tkwindow = tk.Tk()window.title('逃学联盟')window.configure(bg='#008CBA')window.resizable(True, True)window.minsize(100, 100)# window.maxsize(1000, 500)window.state('zoomed')window_width = 500window_height = 100screen_width = window.winfo_screenwidth()screen_height = window.winfo_screenheight()x = int((screen_width - window_width)/2)y = int((screen_height - window_height)/2)window.geometry(f"{window_width}x{window_height}+{x}+{y}")window.iconbitmap('palm-tree-icon.ico')window.mainloop()

    实例1

    鉴于还没有开始其他的tkinter组件,第一个实例借助after方法实现窗口背景色的更换还有窗口的关闭。

    after(delay_ms, callback=None, *args)

    after()方法会每隔delay_ms (毫秒)调用callback的函数。

    window.destroy()方法会关闭window窗口。

    import tkinter as tkimport randomwindow = tk.Tk()window.title('逃学联盟')window.configure(bg='#008CBA')window.resizable(True, True)window.minsize(100, 100)# window.maxsize(1000, 500)window.state('zoomed')window_width = 500window_height = 100screen_width = window.winfo_screenwidth()screen_height = window.winfo_screenheight()x = int((screen_width - window_width)/2)y = int((screen_height - window_height)/2)window.geometry(f"{window_width}x{window_height}+{x}+{y}")window.iconbitmap('palm-tree-icon.ico')bg_color_list = ['#008CBA', '#FFA500', '#4CAF50', '#f44336']def adjust_bg_color():     if bg_color_list:          rand = random.choice(bg_color_list)          window.configure(bg=rand)          window.after(2000, adjust_bg_color)          bg_color_list.remove(rand)     else:          window.destroy()window.after(0, adjust_bg_color)window.mainloop()
    • 定义一个列表 bg_color_list 含有四种不同的颜色代号;
    • 定义callback函数 adjust_bg_color, 如果adjust_bg_color里有值,则随机挑选一个颜色,并更改窗口的bg属性;
    • 每隔2000毫秒调用一次adjust_bg_color;
    • 列表 bg_color_list 中移除被选中的颜色代号;
    • 如果列表 bg_color_list 为空,则关闭窗口;

    感兴趣的同学可以自行运行例子,后面会逐一介绍tkinter的组件。谢谢大家!

    展开全文
  • tkinter库入门详细教程(一):简单窗口的设置

    万次阅读 多人点赞 2018-07-30 23:01:08
    更多内容请看tkinter库入门详细教程(二) 1.初始状态 2.点击按钮后 3.再次点击按钮后 源代码: import tkinter as tk # 设置窗口 window = tk.Tk() # 建立一个窗口 window.title('一个最简单的窗口') ...

    本节主要介绍一个最简单的窗口的设置。更多内容请看tkinter库入门详细教程(二)

    1.初始状态

    2.点击按钮后

    3.再次点击按钮后

    源代码:

    import tkinter as tk
    
    
    # 设置窗口
    window = tk.Tk()  # 建立一个窗口
    window.title('一个最简单的窗口')
    window.geometry('300x200')  # 窗口大小为300x200
    
    
    var = tk.StringVar()  # 文字变量储存器
    
    
    # 设置标签
    l = tk.Label(textvar=var, bg='yellow', width=20, height=2)  # 参数textvar不同于text,bg是backgroud
    l.pack()  # 放置标签
    
    
    bon = False
    
    
    def hit_me():  # 该函数实现按一次按钮显示出字,再按一次字消失
        global bon  # bon为全局变量
        if bon == False:
            bon = True
            var.set('惊喜想得美')
        else:
            bon = False
            var.set('')
    
    
    # 设置按钮
    b = tk.Button(text='点击我有惊喜', width=20, height=2, command=hit_me)
    b.pack()
    
    
    window.mainloop()  # 循环,时刻刷新窗口

    更多内容请看tkinter库入门详细教程(二)

    注:题目来源于莫烦python

    展开全文
  • 【Python】GUI编程(Tkinter)教程

    万次阅读 多人点赞 2020-05-20 21:16:00
    什么是TkinterTkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。 由于 Tkinter 是内置到 python 的安装包中、只要安装好 Python 之后就能 import Tkinter 库、而且 IDLE 也是...

    什么是Tkinter?

    Tkinter 是 Python 的标准 GUI 库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。

    由于 Tkinter 是内置到 python 的安装包中、只要安装好 Python 之后就能 import Tkinter 库、而且 IDLE 也是用 Tkinter 编写而成、对于简单的图形界面 Tkinter 还是能应付自如。

    使用

    导入

    import tkinter
    

    注意:Python3.x 版本使用的库名为 tkinter,即首写字母 T 为小写。

    创建一个GUI程序

    • 1、导入 Tkinter 模块
    • 2、创建控件
    • 3、指定这个控件的 master, 即这个控件属于哪一个
    • 4、告诉 GM(geometry manager) 有一个控件产生了。
    #!/usr/bin/python3
     
    import tkinter
    top = tkinter.Tk()
    # 进入消息循环
    top.mainloop()
    

    窗口主体框架 

    每一个 tkinter 应用的主体框架都可以包含下面这部分. 定义 window 窗口 和 window的一些属性, 然后书写窗口内容, 最后执行window.mainloop让窗口活起来.

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    window.geometry('500x500')
    #注意:这里的乘是×不是* # 这里是窗口的内容 window.mainloop()

     窗口内容

     Label & Button 标签和按钮

    这次我们会建立一个用来描述的标签 tk.Label, 比如:

    import tkinter as tk
    #创建窗口
    window=tk.Tk()
    window.title('Mywindow')#窗口的标题
    window.geometry('200x100')#窗口的大小
    #定义一个label
    l = tk.Label(window, 
        text='Hi! this is TK!',    # 标签的文字
        bg='green',     # 标签背景颜色
        font=('Arial', 12),     # 字体和字体大小
        width=15, height=2  # 标签长宽(以字符长度计算)
        )
    l.pack()    # 固定窗口位置
    
    window.mainloop()
    

    关于Label的更多内容可以看这里https://www.runoob.com/python/python-tk-label.html

     我们也可以通过变量的形式控制标签的显示, 这时我们引入按钮 tk.Button 的概念, 没点一次按钮, 标签变化一次. 用一下内容替换上面的标签. 并把需要变化的文字存成变量 var:

    var = tk.StringVar()    # 这时文字变量储存器
    l = tk.Label(window, 
        textvariable=var,   # 使用 textvariable 替换 text, 因为这个可以变化
        bg='green', font=('Arial', 12), width=15, height=2)
    l.pack() 
    

    接着我们来做 按钮 tk.Button:

    b = tk.Button(window, 
        text='hit me',      # 显示在按钮上的文字
        width=15, height=2, 
        command=hit_me)     # 点击按钮式执行的命令
    b.pack()    # 按钮位置
    

    那么点击是的命令我们用 if else 语句来判断. 用 on_hit 来判断当前状态.

    on_hit = False  # 默认初始状态为 False
    def hit_me():
        global on_hit
        if on_hit == False:     # 从 False 状态变成 True 状态
            on_hit = True
            var.set('you hit me')   # 设置标签的文字为 'you hit me'
        else:       # 从 True 状态变成 False 状态
            on_hit = False
            var.set('') # 设置 文字为空
    

    完整代码:

    import tkinter as tk
    #创建窗口
    window=tk.Tk()
    window.title('Mywindow')#窗口的标题
    window.geometry('200x100')#窗口的大小
    #定义一个label
    var=tk.StringVar()#定义一个字符串变量
    l = tk.Label(window, 
        textvariable=var,    # 标签的文字
        bg='green',     # 标签背景颜色
        font=('Arial', 12),     # 字体和字体大小
        width=15, height=2  # 标签长宽
        )
    l.pack()    # 固定窗口位置
    #定义一个全局变量,来表明字符显示与不显示
    on_hit=False
    
    #按钮的函数
    def hit_me():
        global on_hit#声明全局变量
        if on_hit==False:
            on_hit=True
            var.set('You hit me!')
        else:
            on_hit=False
            var.set('')
    #按钮
    b=tk.Button(window,text='点我',width=15,height=2,command=hit_me)#点击按钮执行一个名为“hit_me”的函数
    b.pack()
    
    window.mainloop()
    

    没有点击时:

    Label & Button 标签和按钮

    点击第一次:

    Label & Button 标签和按钮

    点击第二次:

    Label & Button 标签和按钮

    Entry & Text 输入, 文本框

    窗口主体框架 

    每一个tkinter应用的主体框架都包含以下几部分:

    • 主窗口: window,及主窗口的一些基本属性(标题、大小)
    • 让窗口活起来:window.mainloop()
    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    
    ##窗口尺寸
    window.geometry('200x200')
    
    ##显示出来
    window.mainloop()
    

    窗口内容(窗口上的控件)

    创建按钮分别触发两种情况

    b1 = tk.Button(window,text="insert point",width=15,height=2,command=insert_point)
    b1.pack()
    
    b2 = tk.Button(window,text="insert end",command=insert_end)
    b2.pack()
    

    创建输入框entry,用户输入任何内容都显示为*

    e = tk.Entry(window,show='*')
    e.pack()
    

    创建一个文本框用于显示

    t = tk.Text(window,height=2)
    t.pack()
    

    定义触发事件时的函数(注意:因为Python的执行顺序是从上往下,所以函数一定要放在按钮的上面)

    def insert_point():
        var = e.get()
        t.insert('insert',var)
    
    def insert_end():
        var = e.get()
        t.insert('end',var)
    

    完整代码:

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    #定义一个输入框entry
    e=tk.Entry(window,show=None)#如果是输入密码,可以写show='*'
    e.pack()
    #定义按钮功能
    def insert_point():
        var=e.get()
        t.insert('insert',var)
    def insert_end():
        var=e.get()
        t.insert('end',var)#这里还可以定义字符串插入的具体位置,比如t.insert('1.1',var),表示插入到第一行第一列
    
    #定义2个按钮 Button b1 = tk.Button(window,text="insert point",width=15,height=2,command=insert_point) b1.pack() b2 = tk.Button(window,text="insert end",command=insert_end) b2.pack() #定义一个文本框 Text t=tk.Text(window,height=2) t.pack() ##显示出来 window.mainloop()
    

    窗口界面

    测试一下 

    第一次:在entry中输入tkinter,在text中输入0000并将光标定位在中间位置,点击insert point

    Entry & Text 输入, 文本框

    第二次:点击insert end

    Entry & Text 输入, 文本框

     Listbox 列表部件

    创建主窗口

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    
    
    ##显示出来
    window.mainloop()
    

    创建一个label用于显示 

    var1 = tk.StringVar()    #创建变量
    l =tk.Label(window,bg='yellow',width=4,textvariable=var1)
    l.pack()
    

    创建一个方法用于按钮的点击事件

    def print_selection():
        value = lb.get(lb.curselection())   #获取当前选中的文本
        var1.set(value)     #为label设置值
    

    创建一个按钮

    b1 = tk.Button(window, text='print selection', width=15,
                  height=2, command=print_selection)
    b1.pack()
    

    创建一个Listbox和变量var2,并将var2的值赋给Listbox

    var2 = tk.StringVar()
    var2.set((11,22,33,44)) #为变量设置值
    
    #创建Listbox
    
    lb = tk.Listbox(window, listvariable=var2)  #将var2的值赋给Listbox
    
    #创建一个list并将值循环添加到Listbox控件中
    list_items = [1,2,3,4]
    for item in list_items:
        lb.insert('end', item)  #从最后一个位置开始加入值
    lb.insert(1, 'first')       #在第一个位置加入'first'字符
    lb.insert(2, 'second')      #在第二个位置加入'second'字符
    lb.delete(2)                #删除第二个位置的字符
    lb.pack()
    

    完整代码:

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    #创建一个lable
    var1 = tk.StringVar()    #创建变量
    l =tk.Label(window,bg='yellow',width=4,textvariable=var1)
    l.pack()
    #按钮事件
    def print_selection():
        value = lb.get(lb.curselection())   #获取当前选中的文本
        var1.set(value)     #为label设置值
    #创建一个按钮
    b1 = tk.Button(window, text='print selection', width=15,
                  height=2, command=print_selection)
    b1.pack()
    #创建一个Listbox和变量var2,并将var2的值赋给Listbox
    var2 = tk.StringVar()
    var2.set((11,22,33,44)) #为变量设置值
    
    #创建Listbox
    
    lb = tk.Listbox(window, listvariable=var2)  #将var2的值赋给Listbox
    
    #创建一个list并将值循环添加到Listbox控件中
    list_items = [1,2,3,4]#定义列表
    for item in list_items:
        lb.insert('end', item)  #从最后一个位置开始加入值
    lb.insert(1, 'first')       #在第一个位置加入'first'字符
    lb.insert(2, 'second')      #在第二个位置加入'second'字符
    lb.delete(2)                #删除第二个位置的字符
    lb.pack()
    
    
    ##显示出来
    window.mainloop()
    

    演示

    Radiobutton 选择按钮

    这一次的效果将会像下面的图片一样.

    Radiobutton 选择按钮

    如果选择了某个选项, 效果就会如下.

    Radiobutton 选择按钮

    radiobutton 部件

    首先我们需要定义一个 var 用来将 radiobutton 的值和 Label 的值联系在一起. 然后创建一个radiobutton部分:

    var = tk.StringVar()
    l = tk.Label(window, bg='yellow', width=20, text='empty')
    l.pack()
    
    r1 = tk.Radiobutton(window, text='Option A',
                        variable=var, value='A',
                        command=print_selection)
    r1.pack()
    

    其中variable=varvalue='A'的意思就是,当我们鼠标选中了其中一个选项,把value的值A放到变量var中,然后赋值给variable

    触发功能

    我们将定义一个功能, 用来对选择的 radiobutton 进行操作. print_selection 功能就是选择了某个 radiobutton 后我们会在屏幕上打印的选项.

    def print_selection():
        l.config(text='you have selected ' + var.get())
    

    当触发这个函数功能时,我们的 label 中就会显示 text 所赋值的字符串即 ‘you have selected’, 后面则是我们所选中的选项 var.get()就是获取到变量 var 的值, 举个例子就是我们一开始所做的将选项 “option A” 选中时的值以 “A” 放入 var 中, 所以获取的也就是A 即如果我们这时候选中 “option A” 选项,label显示的值则是 “you have selected A”.

    完整代码:

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    #创建一个lable
    var= tk.StringVar()    #创建变量
    l =tk.Label(window,bg='yellow',width=20,height=2,text='empty')
    l.pack()
    #实现将选择的选项显示在lable
    def print_selection():
        l.config(text='you have selected'+var.get())
    
    #创建几个Radiobutton
    r1 = tk.Radiobutton(window, text='Option A',
                        variable=var, value='A',
                        command=print_selection)
    r1.pack()
    
    r2 = tk.Radiobutton(window, text='Option B',
                        variable=var, value='B',
                        command=print_selection)
    r2.pack()
    
    r3 = tk.Radiobutton(window, text='Option C',
                        variable=var, value='C',
                        command=print_selection)
    r3.pack()
    
    ##显示出来
    window.mainloop()
    

    演示:

     Scale 尺度

    这一次的效果将会像下面的图片一样.

    Scale 尺度

    如果拖动滚动条, 效果就会如下.

    Scale 尺度

    Scale 尺度

    scale 部件

    s = tk.Scale(window, label='try me', from_=5, to=11, orient=tk.HORIZONTAL,
                 length=200, showvalue=0, tickinterval=2, resolution=0.01, command=print_selection)
    s.pack()
    

    这里的参数label是指scale部件的名称,即在这里scale部件名称为try me

    • 参数from_=5,to=11的意思就是从5到11,即这个滚动条最小值为5,最大值为11(这里使用from_是因为在python中有from这个关键词)
    • 参数orient=tk.HORIZONTAL在这里就是设置滚动条的方向,如我们所看到的效果图,这里HORIZONTAL就是横向。
    • 参数length这里是指滚动条部件的长度,但注意的是和其他部件width表示不同,width表示的是以字符为单位,比如width=4,就是4个字符的长度,而此处的length=200,是指我们常用的像素为单位,即长度为200个像素
    • 参数resolution=0.01这里我们可以借助数学题来理解,我们做的很多数学题都会让我们来保留几位小数,此处的0.01就是保留2位小数,即效果图中的5.00 9.00等等后面的两位小数,如果保留一位就是resolution=0.1 这里的showvalue就是设置在滚动条上方的显示。showvalue=0显示的就是效果图,上方无结果显示,如果改为showvalue=1,则会显示为:

    Scale 尺度

    参数tickinterval设置的就是坐标的间隔,此处为tickinterval=2,显示的即为效果图中的5.00 7.00 9.00 11.00 如果改为tickinterval=3则为5.00 8.00 11.00:

    Scale 尺度

    触发功能 

    l = tk.Label(window, bg='yellow', width=20, text='empty')
    l.pack()
    
    def print_selection(v):
        l.config(text='you have selected ' + v)
    

    这里相比前面多了参数v,这里的参数v即将滚动条定位的数据,即如效果图中最开始,定位到5.00,label中显示you have selected 5.00

    完整代码:

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    #创建一个label
    
    l =tk.Label(window,bg='yellow',width=20,height=2,text='empty')
    l.pack()
    #实现将选择的选项显示在lable
    def print_selection(v):
        l.config(text='you have selected'+v)
    #创建一个Scale
    s=tk.Scale(window,label='Try me',from_=5,to=11,orient=tk.HORIZONTAL,
    length=200,showvalue=1,tickinterval=3,resolution=0.01,command=print_selection)
    s.pack()
    
    ##显示出来
    window.mainloop()
    

     Checkbutton 勾选项

    运行之后的效果将会像下面的图片一样,此时不作任何操作.

    Checkbutton 勾选项

    如果只选中第一个选项,即图中的python, 效果就会如下.

    Checkbutton 勾选项

    如果只选中第二个选项,即图中的c++, 效果就会如下.

    Checkbutton 勾选项

    如果两个选项都选中, 效果就会如下.

    Checkbutton 勾选项

    如果两个选项都不选中, 效果就会如下.

    Checkbutton 勾选项

    Checkbutton部件

    var1 = tk.IntVar()
    c1 = tk.Checkbutton(window, text='Python', variable=var1, onvalue=1, offvalue=0,
                        command=print_selection)
    c1.pack()
    

    参数onvalue和前面讲的部件radiobutton中的value相似, 当我们选中了这个checkbutton,onvalue的值1就会放入到var1中, 然后var1将其赋值给参数variableoffvalue用法相似,但是offvalue是在没有选中这个checkbutton时,offvalue的值1放入var1,然后赋值给参数variable 这是创建一个checkbutton部件,以此类推,可以创建多个checkbutton

    触发功能

    def print_selection():
        if (var1.get() == 1) & (var2.get() == 0):   #如果选中第一个选项,未选中第二个选项
            l.config(text='I love only Python ')
        elif (var1.get() == 0) & (var2.get() == 1): #如果选中第二个选项,未选中第一个选项
            l.config(text='I love only C++')
        elif (var1.get() == 0) & (var2.get() == 0):  #如果两个选项都未选中
            l.config(text='I do not love either')
        else:
            l.config(text='I love both')             #如果两个选项都选中
    

    相对于前面学过的 print_selection,这一段比较长,其实功能差不多,只不过加了if...elif...else来选择控制而已即如代码注释,config在前面已经讲过就是将参数text的值显示,这里的var1.get() == 1 就是前面所说的var1获得的变量onvalue=1var1.get() == 0即是var1获得的变量offvalu=0同理var2也是如此。

    完整代码:

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    #创建一个lable
    
    l =tk.Label(window,bg='yellow',width=20,height=2,text='empty')
    l.pack()
    #实现将选择的选项显示在lable
    def print_selection():
        if (var1.get() == 1) & (var2.get() == 0):   #如果选中第一个选项,未选中第二个选项
            l.config(text='I love only Python ')
        elif (var1.get() == 0) & (var2.get() == 1): #如果选中第二个选项,未选中第一个选项
            l.config(text='I love only C++')
        elif (var1.get() == 0) & (var2.get() == 0):  #如果两个选项都未选中
            l.config(text='I do not love anything')
        else:
            l.config(text='I love both')             #如果两个选项都选中
    
    var1=tk.IntVar()
    var2=tk.IntVar()
    #创建2个cheakButton
    cl=tk.Checkbutton(window,text='Python',variable=var1,onvalue=1,offvalue=0,command=print_selection)
    cl.pack()
    c2=tk.Checkbutton(window,text='C++',variable=var2,onvalue=1,offvalue=0,command=print_selection)
    c2.pack()
    ##显示出来
    window.mainloop()
    

    演示:

    Canvas 画布

    运行之后的效果将会像下面的图片一样.

    Canvas 画布

    如果点击move这个button, 效果就会如下.

    Canvas 画布

    Canvas部件

    canvas = tk.Canvas(window, bg='blue', height=100, width=200)
    canvas.pack()
    

    这里的参数和以往学过的部件一样,所以就不再一一解释。 如果你想下载那个 instagram 的图标, 可以点击这里下载, 或者直接右键保存下面的图像.

    Canvas 画布

    image_file = tk.PhotoImage(file='ins.gif')
    image = canvas.create_image(10, 10, anchor='nw', image=image_file)
    

    这里的代码主要是实现我们最终看到的在左上角的那张小图片。 image_file = tk.PhotoImage(file='ins.gif')这一句是创造一个变量存放ins.gif这张图片。 image = canvas.create_image(10, 10, anchor='nw', image=image_file)里面的参数10,10就是图片放入画布的坐标, 而这里的anchor=nw则是把图片的左上角作为锚定点,在加上刚刚给的坐标位置,即可将图片位置确定。 最后一个参数的意思大家应该都知道,就是将刚刚存入的图片变量,赋值给image

    x0, y0, x1, y1= 50, 50, 80, 80
    line = canvas.create_line(x0, y0, x1, y1)
    

    这段代码主要实现的是画一条直线,后面()中给的参数就是线段两点的坐标,两点确定一条直线。此处给的就是从坐标(50,50)到(80,80)画一条直线。

    oval = canvas.create_oval(x0, y0, x1, y1, fill='red')  #创建一个圆,填充色为`red`红色
    arc = canvas.create_arc(x0+30, y0+30, x1+30, y1+30, start=0, extent=180)  #创建一个扇形
    rect = canvas.create_rectangle(100, 30, 100+20, 30+20)   #创建一个矩形
    

    这里面就是创建扇形时多了两个没见过的参数start=0extent=180,其实就是从0度到180度,就好像扇子的边打开一样。在我们看来就是个半圆, 如果改为extent=90,我们看到的就是一个1/4圆

    触发功能 

    def moveit():
        canvas.move(rect, 0, 2)
    

    这里的触发不再是以往的print_selection了,哈哈,那么这里的是怎么样的功能呢,首先我们从单词理解来看就是移动的函数,在视频中也演示过了, 就是我们每点一次button 矩形就会移动这里canvas.move(rect, 0, 2)的参数(rect,0,2)就是移动rect这个变量,即我们看到的矩形 后面的0和2,也就是横坐标移动0个单位,纵坐标移动2个单位,简单的说就是每次点击,横向不动,纵向移动两个单位。

    完整代码:

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    #新建画布
    #显示图片
    canvas=tk.Canvas(window,bg='blue',height=100,width=200)
    image_file=tk.PhotoImage(file='ins.gif')
    image=canvas.create_image(0,0,anchor='nw',image=image_file)
    #画线
    x0,y0,x1,y1=50,50,80,80
    line=canvas.create_line(x0,y0,x1,y1)
    #画⚪
    oval=canvas.create_oval(x0,y0,x1,y1,fill='red')
    #画一个扇形
    arc = canvas.create_arc(x0+30, y0+30, x1+30, y1+30, start=0, extent=90)  
    #画一个矩形
    rect = canvas.create_rectangle(100, 30, 100+20, 30+20)   
    canvas.pack()
    def moveit():
        canvas.move(rect,0,2)
    
    #创建一个Button
    b=tk.Button(window,text='Move',command=moveit)
    b.pack()
    ##显示出来
    window.mainloop()
    

    演示:

    Menubar 菜单

    这一次的效果将会像下面的图片一样.

    Menubar 菜单

    注意这里的操作系统是苹果的 MacOS, 它的菜单栏位置和 Windows 的不一样.

    Menubar 菜单

    Menubar 菜单

    下面是我们制作整个菜单栏的流程, 我们先需要加入一个 Menubar 作为整体框架, 然后再在 Menubar 中加一些部件.

    ##创建一个菜单栏,这里我们可以把他理解成一个容器,在窗口的上方
    menubar = tk.Menu(window)
    
    ##定义一个空菜单单元
    filemenu = tk.Menu(menubar, tearoff=0)
    
    ##将上面定义的空菜单命名为`File`,放在菜单栏中,就是装入那个容器中
    menubar.add_cascade(label='File', menu=filemenu)
    
    ##在`File`中加入`New`的小菜单,即我们平时看到的下拉菜单,每一个小菜单对应命令操作。
    ##如果点击这些单元, 就会触发`do_job`的功能
    filemenu.add_command(label='New', command=do_job)
    filemenu.add_command(label='Open', command=do_job)##同样的在`File`中加入`Open`小菜单
    filemenu.add_command(label='Save', command=do_job)##同样的在`File`中加入`Save`小菜单
    
    filemenu.add_separator()##这里就是一条分割线
    
    ##同样的在`File`中加入`Exit`小菜单,此处对应命令为`window.quit`
    filemenu.add_command(label='Exit', command=window.quit)
    

    同样的我们在定义另一个菜单Edit也是如此和定义的File菜单一样 这里再来看一下效果中比较不一样的菜单就是File中的Import菜单, 在这个菜单选项中, 我们还能分支出更多的选项.

    submenu = tk.Menu(filemenu)##和上面定义菜单一样,不过此处实在`File`上创建一个空的菜单
    filemenu.add_cascade(label='Import', menu=submenu, underline=0)##给放入的菜单`submenu`命名为`Import`
    submenu.add_command(label="Submenu1", command=do_job)##这里和上面也一样,在`Import`中加入一个小菜单命令`Submenu1`
    

    触发功能

    counter = 0
    def do_job():
        global counter
        l.config(text='do '+ str(counter))
        counter+=1
    

    这里的功能就是每触发一次命令,counter就会+1,在label上的显示就会从 do 0 ,do 1 , do 2…

    完整代码:

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    #新建一个label
    l=tk.Label(window,text='',bg='yellow')
    l.pack()
    #计数
    counter = 0
    def do_job():
        global counter
        l.config(text='do '+ str(counter))
        counter+=1
    #创建菜单
    menubar=tk.Menu(window)
    #菜单一
    filemenu=tk.Menu(menubar,tearoff=0)
    #一级菜单
    menubar.add_cascade(label='File',menu=filemenu)
    #二级菜单
    filemenu.add_command(label='New',command=do_job)
    filemenu.add_command(label='Open',command=do_job)
    filemenu.add_separator()#分割线
    filemenu.add_command(label='Exit',command=window.quit)
    #菜单二
    editmenu=tk.Menu(menubar,tearoff=0)
    #一级菜单
    menubar.add_cascade(label='Edit',menu=editmenu)
    #二级菜单
    editmenu.add_command(label='Cut',command=do_job)
    editmenu.add_command(label='Paste',command=do_job)
    #
    #菜单一子菜单
    submenu=tk.Menu(filemenu)
    #一级菜单
    filemenu.add_cascade(label='Import',menu=submenu,underline=0)
    #二级菜单
    submenu.add_command(label='Submeau1',command=do_job)
    submenu.add_command(label='Submeau1',command=do_job)
    
    window.config(menu=menubar)
    ##显示出来
    window.mainloop()
    

    演示:

    Frame 框架

    这一次的效果将会像下面的图片一样.

    Frame 框架

    Frame 部件 

    Frame 是一个在 Windows 上分离小区域的部件, 它能将 Windows 分成不同的区,然后存放不同的其他部件. 同时一个 Frame 上也能再分成两个 Frame, Frame 可以认为是一种容器.

    ###定义一个`label`显示`on the window`
    tk.Label(window, text='on the window').pack()
    
    ###在`window`上创建一个`frame`
    frm = tk.Frame(window)
    frm.pack()
    
    ###在刚刚创建的`frame`上创建两个`frame`,我们可以把它理解成一个大容器里套了一个小容器,即`frm`上有两个`frame` ,`frm_l`和`frm_r`
    
    frm_l = tk.Frame(frm)
    frm_r = tk.Frame(frm)
    
    ###这里是控制小的`frm`部件在大的`frm`的相对位置,此处`frm_l`就是在`frm`的左边,`frm_r`在`frm`的右边
    frm_l.pack(side='left')
    frm_r.pack(side='right')
    
    ###这里的三个label就是在我们创建的frame上定义的label部件,还是以容器理解,就是容器上贴了标签,来指明这个是什么,解释这个容器。
    tk.Label(frm_l, text='on the frm_l1').pack()##这个`label`长在`frm_l`上,显示为`on the frm_l1`
    tk.Label(frm_l, text='on the frm_l2').pack()##这个`label`长在`frm_l`上,显示为`on the frm_l2`
    tk.Label(frm_r, text='on the frm_r1').pack()##这个`label`长在`frm_r`上,显示为`on the frm_r1`
    

    完整代码:

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    ###定义一个`label`显示`on the window`
    tk.Label(window, text='on the window').pack()
    
    ###在`window`上创建一个`frame`
    frm = tk.Frame(window,bg='green')
    frm.pack()
    
    ###在刚刚创建的`frame`上创建两个`frame`,我们可以把它理解成一个大容器里套了一个小容器,即`frm`上有两个`frame` ,`frm_l`和`frm_r`
    
    frm_l = tk.Frame(frm,bg='red')
    frm_r = tk.Frame(frm,bg='blue')
    
    ###这里是控制小的`frm`部件在大的`frm`的相对位置,此处`frm_l`就是在`frm`的左边,`frm_r`在`frm`的右边
    frm_l.pack(side='left')
    frm_r.pack(side='right')
    
    ###这里的三个label就是在我们创建的frame上定义的label部件,还是以容器理解,就是容器上贴了标签,来指明这个是什么,解释这个容器。
    tk.Label(frm_l, text='on the frm_l1',bg='red').pack()##这个`label`长在`frm_l`上,显示为`on the frm_l1`
    tk.Label(frm_l, text='on the frm_l2',bg='red').pack()##这个`label`长在`frm_l`上,显示为`on the frm_l2`
    tk.Label(frm_r, text='on the frm_r1',bg='blue').pack()##这个`label`长在`frm_r`上,显示为`on the frm_r1`
    ##显示出来
    window.mainloop()
    

    演示:

    messagebox 弹窗

    其实这里的messagebox就是我们平时看到的弹窗。 我们首先需要定义一个触发功能,来触发这个弹窗 这里我们就放上以前学过的button按钮

    tk.Button(window, text='hit me', command=hit_me).pack()
    

    通过触发功能,调用messagebox

    def hit_me():
       tk.messagebox.showinfo(title='Hi', message='hahahaha')
    

    这里点击button按钮就会弹出提示对话窗

     下面给出几种形式

    tk.messagebox.showinfo(title='',message='')#提示信息对话窗
    tk.messagebox.showwarning()#提出警告对话窗
    tk.messagebox.showerror()#提出错误对话窗
    tk.messagebox.askquestion()#询问选择对话窗
    

    如果给出如下定义就是打印出我们所选项对应的值

    def hit_me():
       print(tk.messagebox.askquestion(title='Hi', message='hahahaha'))
    

     同样创建方法都是一样的形式

     print(tk.messagebox.askquestion())#返回yes和no
        print(tk.messagebox.askokcancel())#返回true和false
        print(tk.messagebox.askyesno())#返回true和false
        print(tk.messagebox.askretrycancel())#返回true和false
    

    完整代码:

    import tkinter as tk
    import tkinter.messagebox
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    def hit_me():
        #tk.messagebox.showinfo(title='',message='')#提示信息对话窗
        #tk.messagebox.showwarning()#提出警告对话窗
        #tk.messagebox.showerror()#提出错误对话窗
        #tk.messagebox.askquestion(title='Hi', message='hahahaha')#询问选择对话窗
        print(tk.messagebox.askquestion(title='Hi', message='hahahaha'))#打印出我们所选项对应的值
    tk.Button(window,text='Hit me',command=hit_me).pack()
    
    ##显示出来
    window.mainloop()
    

    演示:

    pack grid place 放置位置

    pack 

    首先我们先看看我们常用的pack(), 他会按照上下左右的方式排列.

    tk.Label(window, text='1').pack(side='top')#上
    tk.Label(window, text='1').pack(side='bottom')#下
    tk.Label(window, text='1').pack(side='left')#左
    tk.Label(window, text='1').pack(side='right')#右
    

    grid 

    接下里我们在看看grid(), grid 是方格, 所以所有的内容会被放在这些规律的方格中.

    for i in range(4):
        for j in range(3):
            tk.Label(window, text=1).grid(row=i, column=j, padx=10, pady=10)
    

    以上的代码就是创建一个四行三列的表格,其实grid就是用表格的形式定位的。这里的参数 row为行,colum为列,padx就是单元格左右间距,pady就是单元格上下间距。

     

    place 

    再接下来就是place(), 这个比较容易理解,就是给精确的坐标来定位,如此处给的(20,10),就是将这个部件放在坐标为(x,y)的这个位置 后面的参数anchor=nw就是前面所讲的锚定点是西北角。

    tk.Label(window, text=1).place(x=20, y=10, anchor='nw')
    

     完整代码(只能用一种方式放置):

    import tkinter as tk
    
    window = tk.Tk()
    window.title('my window')
    ##窗口尺寸
    window.geometry('200x200')
    #pack
    tk.Label(window, text='1').pack(side='top')#上
    tk.Label(window, text='1').pack(side='bottom')#下
    tk.Label(window, text='1').pack(side='left')#左
    tk.Label(window, text='1').pack(side='right')#右
    #gird
    for i in range(4):
        for j in range(3):
            tk.Label(window, text=1).grid(row=i, column=j, padx=10, pady=10)
    #place
    tk.Label(window, text=1).place(x=20, y=10, anchor='nw')
    ##显示出来
    window.mainloop()
    

    例子 登录窗口1

    这一次效果图是这样的:

    例子 登录窗口1

    都是前面熟悉的参数。为了防止大家忘记,特意加上代码注释。

    界面创建 

    # welcome image
    canvas = tk.Canvas(window, height=200, width=500)#创建画布
    image_file = tk.PhotoImage(file='welcome.gif')#加载图片文件
    image = canvas.create_image(0,0, anchor='nw', image=image_file)#将图片置于画布上
    canvas.pack(side='top')#放置画布(为上端)
    

    这里创建的就是我们效果图中的welcome, 如果你想使用和我一样的 welcome 的图片, 你可以在这里下载。

    # user information
    tk.Label(window, text='User name: ').place(x=50, y= 150)#创建一个`label`名为`User name: `置于坐标(50,150)
    tk.Label(window, text='Password: ').place(x=50, y= 190)
    
    var_usr_name = tk.StringVar()#定义变量
    var_usr_name.set('example@python.com')#变量赋值'example@python.com'
    entry_usr_name = tk.Entry(window, textvariable=var_usr_name)#创建一个`entry`,显示为变量`var_usr_name`即图中的`example@python.com`
    entry_usr_name.place(x=160, y=150)
    var_usr_pwd = tk.StringVar()
    entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*')#`show`这个参数将输入的密码变为`***`的形式
    entry_usr_pwd.place(x=160, y=190)
    

    这里就是创建我们熟悉的登录界面,就是常见的用户名,密码。

    # login and sign up button
    btn_login = tk.Button(window, text='Login', command=usr_login)#定义一个`button`按钮,名为`Login`,触发命令为`usr_login`
    btn_login.place(x=170, y=230)
    btn_sign_up = tk.Button(window, text='Sign up', command=usr_sign_up)
    btn_sign_up.place(x=270, y=230)
    

    这里定义的就是我们的登录按钮。

    触发功能

    def usr_login():
        pass
    def usr_sign_up():
        pass
    

    本节我们只是把登录的界面做出来,并没有对触发功能详细的去定义。等下节会继续完善这个例子。

    例子 登录窗口2

    这一次效果图是这样的:

    例子 登录窗口2

    触发的 usr_login 功能 

    ##这两行代码就是获取用户输入的`usr_name`和`usr_pwd`
    usr_name = var_usr_name.get()
    usr_pwd = var_usr_pwd.get()
    
    ##这里设置异常捕获,当我们第一次访问用户信息文件时是不存在的,所以这里设置异常捕获。
    ##中间的两行就是我们的匹配,即程序将输入的信息和文件中的信息匹配。
    try:
        with open('usrs_info.pickle', 'rb') as usr_file:
            usrs_info = pickle.load(usr_file)
    except FileNotFoundError:
     ##这里就是我们在没有读取到`usr_file`的时候,程序会创建一个`usr_file`这个文件,并将管理员
     ##的用户和密码写入,即用户名为`admin`密码为`admin`。
        with open('usrs_info.pickle', 'wb') as usr_file:
            usrs_info = {'admin': 'admin'}
            pickle.dump(usrs_info, usr_file)
    

    这一部分就是将用户输入的用户名和密码获取到,和我们保存在usr_file中的数据对比。针对正确的密码和错误的密码分别对待.

    #如果用户名和密码与文件中的匹配成功,则会登录成功,并跳出弹窗`how are you?`加上你的用户名。
    if usr_name in usrs_info:
        if usr_pwd == usrs_info[usr_name]:
            tk.messagebox.showinfo(title='Welcome', message='How are you? ' + usr_name)
        ##如果用户名匹配成功,而密码输入错误,则会弹出'Error, your password is wrong, try again.'
        else:
            tk.messagebox.showerror(message='Error, your password is wrong, try again.')
    else:   # 如果发现用户名不存在
        is_sign_up = tk.messagebox.askyesno('Welcome',
                               'You have not sign up yet. Sign up today?')
        # 提示需不需要注册新用户
        if is_sign_up:
            usr_sign_up()
    

    下面是用户名存在但是一个密码正确, 一个密码错误.

    例子 登录窗口2

    例子 登录窗口2

    下面是用户不存在, 提示需不需要注册一个新的用户.

    例子 登录窗口2

    因为本节只是定义usr_sign_up并没有实质功能,所以选择之后没有太大变化。 这一部分就是匹配的主要内容,如果匹配成功,就会登录进去,否则就会失败。

    本节主要是详细介绍登录功能,下节会继续完善注册命令。 

    例子 登录窗口3

    这一次效果图是这样的:

    例子 登录窗口3

    usr_sign_up 界面

    window_sign_up = tk.Toplevel(window)
    window_sign_up.geometry('350x200')
    window_sign_up.title('Sign up window')
    

    这一段首先是创建一个注册的窗口。这里和以往不同的是,多了一个tk.Toplevel我们打个比方,就好像我们前面所学 的frame一样,就是在编辑的功能下还有很多功能一样,这里就是在主体窗口的window上创建一个Sign up window窗口。

    new_name = tk.StringVar()#将输入的注册名赋值给变量
    new_name.set('example@python.com')#将最初显示定为'example@python.com'
    tk.Label(window_sign_up, text='User name: ').place(x=10, y= 10)#将`User name:`放置在坐标(10,10)。
    entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)#创建一个注册名的`entry`,变量为`new_name`
    entry_new_name.place(x=150, y=10)#`entry`放置在坐标(150,10).
    
    new_pwd = tk.StringVar()
    tk.Label(window_sign_up, text='Password: ').place(x=10, y=50)
    entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')
    entry_usr_pwd.place(x=150, y=50)
    
    new_pwd_confirm = tk.StringVar()
    tk.Label(window_sign_up, text='Confirm password: ').place(x=10, y= 90)
    entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')
    entry_usr_pwd_confirm.place(x=150, y=90)
    
    # 下面的 sign_to_Mofan_Python 我们再后面接着说
    btn_comfirm_sign_up = tk.Button(window_sign_up, text='Sign up', command=sign_to_Mofan_Python)
    btn_comfirm_sign_up.place(x=150, y=130)
    

    相信大家对这一段代码已经很熟悉了,因为这是大家前面所学过的知识。其实就是像我们平时所见的注册窗口有一样,在Sign up window窗口 上添加new_name new_pwd, new_pwd_confirm,还有最后一个注册按钮。这里便于大家复习,我们将new_name这段详细介绍一下(如代码注释)。 到这里就完成了我们这个注册的主要界面用户名,密码,确认密码。效果图如下:

    例子 登录窗口3

    sign_to_Mofan_Python() 功能 

    def usr_sign_up():
        def sign_to_Mofan_Python():
            ##以下三行就是获取我们注册时所输入的信息
            np = new_pwd.get()
            npf = new_pwd_confirm.get()
            nn = new_name.get()
    
            ##这里是打开我们记录数据的文件,将注册信息读出
            with open('usrs_info.pickle', 'rb') as usr_file:
                exist_usr_info = pickle.load(usr_file)
    
            ##这里就是判断,如果两次密码输入不一致,则提示`'Error', 'Password and confirm password must be the same!'`
            if np != npf:
                tk.messagebox.showerror('Error', 'Password and confirm password must be the same!')
    
            ##如果用户名已经在我们的数据文件中,则提示`'Error', 'The user has already signed up!'`
            elif nn in exist_usr_info:
                tk.messagebox.showerror('Error', 'The user has already signed up!')
    
            ##最后如果输入无以上错误,则将注册输入的信息记录到文件当中,并提示注册成功`'Welcome', 'You have successfully signed up!'`
            ##然后销毁窗口。
            else:
                exist_usr_info[nn] = np
                with open('usrs_info.pickle', 'wb') as usr_file:
                    pickle.dump(exist_usr_info, usr_file)
                tk.messagebox.showinfo('Welcome', 'You have successfully signed up!')
                ##然后销毁窗口。
                window_sign_up.destroy()
    

    这里其实和前面所讲的login功能类似,如代码注释。

    注册成功就是我们一开始展示的效果图。

    到此,我们的这个程序已经完善。这里给大家奉上我们最后的成果。

    完整代码:

    import tkinter as tk
    import pickle
    import tkinter.messagebox
    window = tk.Tk()
    window.title('Welcome To Myapp!')
    ##窗口尺寸
    window.geometry('450x300')
    # welcome image
    canvas = tk.Canvas(window, height=200, width=500)#创建画布
    image_file = tk.PhotoImage(file='welcome.gif')#加载图片文件
    image = canvas.create_image(0,0, anchor='nw', image=image_file)#将图片置于画布上
    canvas.pack(side='top')#放置画布(为上端)
    # user information
    tk.Label(window, text='用户名: ').place(x=50, y= 150)#创建一个`label`名为`User name: `置于坐标(50,150)
    tk.Label(window, text='密码: ').place(x=50, y= 190)
    #用户名输入框
    var_usr_name = tk.StringVar()#定义变量
    var_usr_name.set('example@python.com')#变量赋值'example@python.com'
    entry_usr_name = tk.Entry(window, textvariable=var_usr_name)#创建一个`entry`,显示为变量`var_usr_name`即图中的`example@python.com`
    entry_usr_name.place(x=160, y=150)
    #密码输入框
    var_usr_pwd = tk.StringVar()
    entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, show='*')#`show`这个参数将输入的密码变为`***`的形式
    entry_usr_pwd.place(x=160, y=190)
    #登录事件
    def usr_login():
        ##这两行代码就是获取用户输入的`usr_name`和`usr_pwd`
        usr_name = var_usr_name.get()
        usr_pwd = var_usr_pwd.get()
    ##这里设置异常捕获,当我们第一次访问用户信息文件时是不存在的,所以这里设置异常捕获。
    ##中间的两行就是我们的匹配,即程序将输入的信息和文件中的信息匹配。
        try:
            with open('usrs_info.pickle', 'rb') as usr_file:
                usrs_info = pickle.load(usr_file)
        except EOFError:
     ##这里就是我们在没有读取到`usr_file`的时候,程序会创建一个`usr_file`这个文件,并将管理员
     ##的用户和密码写入,即用户名为`admin`密码为`admin`。
            with open('usrs_info.pickle', 'wb') as usr_file:
                usrs_info = {'admin': 'admin'}
                pickle.dump(usrs_info, usr_file)
    #如果用户名和密码与文件中的匹配成功,则会登录成功,并跳出弹窗`how are you?`加上你的用户名。
        if usr_name in usrs_info:
            if usr_pwd == usrs_info[usr_name]:
                tk.messagebox.showinfo(title='欢迎', message='你好' + usr_name)
        ##如果用户名匹配成功,而密码输入错误,则会弹出'Error, your password is wrong, try again.'
            else:
                tk.messagebox.showerror(message='错误,你的密码有问题,请重新输入')
        else:   # 如果发现用户名不存在
            is_sign_up = tk.messagebox.askyesno('Welcome',
                               '你还没有注册,现在注册?')
        # 提示需不需要注册新用户
        if is_sign_up:
            usr_sign_up()
    #注册事件
    def usr_sign_up():
        def sign_to_app():
             ##以下三行就是获取我们注册时所输入的信息
            np = new_pwd.get()
            npf = new_pwd_confirm.get()
            nn = new_name.get()
             ##这里是打开我们记录数据的文件,将注册信息读出
            with open('usrs_info.pickle', 'rb') as usr_file:
                exist_usr_info = pickle.load(usr_file)
    
            ##这里就是判断,如果两次密码输入不一致,则提示`'Error', 'Password and confirm password must be the same!'`
            if np != npf:
                tk.messagebox.showerror('Error', '两次密码输入不一致哦!')
    
            ##如果用户名已经在我们的数据文件中,则提示`'Error', 'The user has already signed up!'`
            elif nn in exist_usr_info:
                tk.messagebox.showerror('Error', '这个用户名已经注册了!')
    
            ##最后如果输入无以上错误,则将注册输入的信息记录到文件当中,并提示注册成功`'Welcome', 'You have successfully signed up!'`
            ##然后销毁窗口。
            else:
                exist_usr_info[nn] = np
                with open('usrs_info.pickle', 'wb') as usr_file:
                    pickle.dump(exist_usr_info, usr_file)
                tk.messagebox.showinfo('Welcome', '你成功注册了!')
                ##然后销毁窗口。
                window_sign_up.destroy()
    
        window_sign_up = tk.Toplevel(window)
        window_sign_up.geometry('350x200')
        window_sign_up.title('用户注册')
        #新用户名
        new_name = tk.StringVar()#将输入的注册名赋值给变量
        new_name.set('example@python.com')#将最初显示定为'example@python.com'
        tk.Label(window_sign_up, text='用户名: ').place(x=10, y= 10)#将`User name:`放置在坐标(10,10)。
        entry_new_name = tk.Entry(window_sign_up, textvariable=new_name)#创建一个注册名的`entry`,变量为`new_name`
        entry_new_name.place(x=150, y=10)#`entry`放置在坐标(150,10).
        #新密码
        new_pwd = tk.StringVar()
        tk.Label(window_sign_up, text='密码: ').place(x=10, y=50)
        entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show='*')
        entry_usr_pwd.place(x=150, y=50)
        #防止密码填错
        new_pwd_confirm = tk.StringVar()
        tk.Label(window_sign_up, text='重复密码: ').place(x=10, y= 90)
        entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*')
        entry_usr_pwd_confirm.place(x=150, y=90)
        # 下面的 sign_to_app 
        btn_comfirm_sign_up = tk.Button(window_sign_up, text='注册', command=sign_to_app)
        btn_comfirm_sign_up.place(x=150, y=130)
    
    
    
    
    # 登录和注册按钮
    btn_login = tk.Button(window, text='登录', command=usr_login)#定义一个`button`按钮,名为`Login`,触发命令为`usr_login`
    btn_login.place(x=170, y=230)
    btn_sign_up = tk.Button(window, text='注册', command=usr_sign_up)
    btn_sign_up.place(x=270, y=230)
    
    ##显示出来
    window.mainloop()
    

    演示:

    展开全文
  • Python_Tkinter教程.pdf

    2019-08-14 09:46:41
    本文档详细的介绍了Python的Tkinter图形框架的教程,如果设计图形界面不想安装过多的库和插件,Tkinter再合适不过了,轻量简单,满足GUI设计的基本需求。
  • Python-Tkinter图形化界面设计(详细教程

    万次阅读 多人点赞 2019-08-05 23:07:41
    Python 图形化界面设计 ... 1、图形化界面设计的基本理解 当前流行的计算机桌面应用程序大多数为图形化用户界面(Graphic User Interface,GUI),即通过鼠标对菜单、按钮等图形化...Python自带了tkinter 模块,实质上...

    声明:本篇文章为转载自https://www.jianshu.com/p/91844c5bca78,在原作者的基础上添加目录导航,旨在帮助大家以更高效率进行学习和开发。

    Python-Tkinter 图形化界面设计(详细教程)

    本文目录

    一.图形化界面设计的基本理解

    当前流行的计算机桌面应用程序大多数为图形化用户界面(Graphic User Interface,GUI),即通过鼠标对菜单、按钮等图形化元素触发指令,并从标签、对话框等图型化显示容器中获取人机对话信息。
    Python自带了tkinter 模块,实质上是一种流行的面向对象的GUI工具包 TK 的Python编程接口,提供了快速便利地创建GUI应用程序的方法。其图像化编程的基本步骤通常包括:

    ○ 导入 tkinter 模块
    ○ 创建 GUI 根窗体
    ○ 添加人机交互控件并编写相应的函数。
    ○ 在主事件循环中等待用户触发事件响应。

    二.窗体控件布局

    2.1. 数据集导入

    根窗体是图像化应用程序的根控制器,是tkinter的底层控件的实例。当导入tkinter模块后,调用 Tk()方法可初始化一个根窗体实例 root ,用 title() 方法可设置其标题文字,用geometry()方法可以设置窗体的大小(以像素为单位)。将其置于主循环中,除非用户关闭,否则程序始终处于运行状态。执行该程序,一个窗体就呈现出来了。在这个主循环的根窗体中,可持续呈现中的其他可视化控件实例,监测事件的发生并执行相应的处理程序。下面是根窗体呈现示例:

    from tkinter import *
    root= Tk()
    root.title('我的第一个Python窗体')
    root.geometry('240x240') # 这里的乘号不是 * ,而是小写英文字母 x
    root.mainloop()
    

    在这里插入图片描述

    2.2. tkinter 常用控件

    返回目录

    常用控件:常用的10 多种,如下:
    在这里插入图片描述

    2.2.1 控件的共同属性

    返回目录

    在窗体上呈现的可视化控件,通常包括尺寸、颜色、字体、相对位置、浮雕样式、图标样式和悬停光标形状等共同属性。不同的控件由于形状和功能不同,又有其特征属性。在初始化根窗体和根窗体主循环之间,可实例化窗体控件,并设置其属性。父容器可为根窗体或其他容器控件实例。常见的控件共同属性如下表:
    在这里插入图片描述
    标签及常见属性示例:

    from  tkinter import *
    root = Tk()
    lb = Label(root,text='我是第一个标签',\
            bg='#d3fbfb',\
            fg='red',\
            font=('华文新魏',32),\
            width=20,\
            height=2,\
            relief=SUNKEN)
    lb.pack()
    root.mainloop()
    

    在这里插入图片描述
    其中,标签实例lb 在父容器root中实例化,具有代码中所示的text(文本)、bg(背景色)、fg(前景色)、font(字体)、width(宽,默认以字符为单位)、height(高,默认以字符为单位)和 relief(浮雕样式)等一系列属性。
    在实例化控件时,实例的属性可以“属性=属性值”的形式枚举列出,不区分先后次序。例如:“ text=‘我是第一个标签’ ”显示标签的文本内容,“bg=’#d3fbfb’”设置背景色为十六进制数RGB色 #d3fbfb等等。属性值通常用文本形式表示。
    当然如果这个控件实例只需要一次性呈现,也可以不必命名,直接实例化并布局呈现出来,例如:

    Label(root,text='我是第一个标签',font='华文新魏').pack()
    

    属性 relief 为控件呈现出来的3D浮雕样式,有 FLAT(平的)、RAISED(凸起的)、SUNKEN(凹陷的)、GROOVE(沟槽状边缘)和 RIDGE(脊状边缘) 5种。
    在这里插入图片描述

    2.3 控件布局

    返回目录

    控件的布局通常有pack()、grid() 和 place() 三种方法。
    pack和grid请参考:https://www.jianshu.com/p/91844c5bca78

    2.3.1 place()方法

    返回目录

    根据控件实例在父容器中的绝对或相对位置参数进行布局。其常用布局参数如下:
    x,y:控件实例在根窗体中水平和垂直方向上的其实位置(单位为像素)。注意,根窗体左上角为0,0,水平向右,垂直向下为正方向。
    relx,rely:控件实例在根窗体中水平和垂直方向上起始布局的相对位置。即相对于根窗体宽和高的比例位置,取值在0.0~1.0之间。
    height,width:控件实例本身的高度和宽度(单位为像素)。
    relheight,relwidth:控件实例相对于根窗体的高度和宽度比例,取值在0.0~1.0之间。

    利用place()方法配合relx,rely和relheight,relwidth参数所得的到的界面可自适应根窗体尺寸的大小。place()方法与grid()方法可以混合使用。如下例子:利用place()方法排列消息(多行标签)。
    在这里插入图片描述

    from tkinter import *
    root = Tk()
    root.geometry('320x240')
    
    msg1 = Message(root,text='''我的水平起始位置相对窗体 0.2,垂直起始位置为绝对位置 80 像素,我的高度是窗体高度的0.4,宽度是200像素''',relief=GROOVE)
    msg1.place(relx=0.2,y=80,relheight=0.4,width=200)
    root.mainloop()
    

    三、tkinter常见控件的特征属性

    3.1、文本输入和输出相关控件

    文本的输入与输出控件通常包括:标签(Label)、消息(Message)、输入框(Entry)、文本框(Text)。他们除了前述共同属性外,都具有一些特征属性和功能。

    ○ 3.1.1 标签(Label)和 消息(Message)

    返回目录

    除了单行与多行的不同外,属性和用法基本一致,用于呈现文本信息。值得注意的是:属性text通常用于实例在第一次呈现时的固定文本,而如果需要在程序执行后发生变化,则可以使用下列方法之一实现:1、用控件实例的configure()方法来改变属性text的值,可使显示的文本发生变化;2、先定义一个tkinter的内部类型变量var=StringVar() 的值也可以使显示文本发生变化。
    看下面的一个例子:制作一个电子时钟,用root的after()方法每隔1秒time模块以获取系统当前时间,并在标签中显示出来。
    方法一:利用configure()方法或config()来实现文本变化
    在这里插入图片描述

    import tkinter
    import time
    
    def gettime():
          timestr = time.strftime("%H:%M:%S") # 获取当前的时间并转化为字符串
          lb.configure(text=timestr)   # 重新设置标签文本
          root.after(1000,gettime) # 每隔1s调用函数 gettime 自身获取时间
    
    root = tkinter.Tk()
    root.title('时钟')
    
    lb = tkinter.Label(root,text='',fg='blue',font=("黑体",80))
    lb.pack()
    gettime()
    root.mainloop()
    

    方法二:利用textvariable变量属性来实现文本变化

    import tkinter
    import time
    
    def gettime():
          var.set(time.strftime("%H:%M:%S"))   # 获取当前时间
          root.after(1000,gettime)   # 每隔1s调用函数 gettime 自身获取时间
    
    root = tkinter.Tk()
    root.title('时钟')
    var=tkinter.StringVar()
    
    lb = tkinter.Label(root,textvariable=var,fg='blue',font=("黑体",80))
    lb.pack()
    gettime()
    root.mainloop()
    

    ○ 3.1.2 文本框(Text)

    文本框的常用方法如下:
    在这里插入图片描述
    上表位置的取值可为整数,浮点数或END(末尾),例如0.0表示第0列第0行
    如下一个例子: 每隔1秒获取一次当前日期的时间,并写入文本框中,如下:本例中调用 datetime.now()获取当前日期时间,用insert()方法每次从文本框txt的尾部(END)开始追加文本。
    在这里插入图片描述

    from tkinter import *
    import time
    import datetime
    
    def gettime():
           s=str(datetime.datetime.now())+'\n'
           txt.insert(END,s)
           root.after(1000,gettime)  # 每隔1s调用函数 gettime 自身获取时间
    
    root=Tk()
    root.geometry('320x240')
    txt=Text(root)
    txt.pack()
    gettime()
    root.mainloop()
    

    ○ 3.1.3 输入框(Entry)

    返回目录

    通常作为功能比较单一的接收单行文本输入的控件,虽然也有许多对其中文本进行操作的方法,但通常用的只有取值方法get()和用于删除文本的delete(起始位置,终止位置),例如:清空输入框为delete(0,END)

    3.2 按钮(Button)

    返回目录

    主要是为响应鼠标单击事件触发运行程序所设的,故其除控件共有属性外,属性command是最为重要的属性。通常,将按钮要触发执行的程序以函数形式预先定义,然后可以用一下两种方法调用函数。Button按钮的状态有:'normal','active','disabled'

    ○ 直接调用函数。参数表达式为“command=函数名”,注意函数名后面不要加括号,也不能传递参数。如下面的command=run1:
    ○ 利用匿名函数调用函数和传递参数。参数的表达式为“command=lambda”:函数名(参数列表)。例如下面的:"command=lambda:run2(inp1.get(),inp2.get())"。

    ○ 看下面的例子:1.从两个输入框去的输入文本后转为浮点数值进行加法运算,要求每次单击按钮产生的算是结果以文本的形式追加到文本框中,将原输入框清空。2.按钮方法一不传参数调用函数run1()实现,按钮“方法二”用lambda调用函数run2(x,y)同时传递参数实现。
    在这里插入图片描述

    from tkinter import *
    
    def run1():
         a = float(inp1.get())
         b = float(inp2.get())
         s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b)
         txt.insert(END, s)   # 追加显示运算结果
         inp1.delete(0, END)  # 清空输入
         inp2.delete(0, END)  # 清空输入
    
    def run2(x, y):
         a = float(x)
         b = float(y)
         s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b)
         txt.insert(END, s)   # 追加显示运算结果
         inp1.delete(0, END)  # 清空输入
         inp2.delete(0, END)  # 清空输入
    
    root = Tk()
    root.geometry('460x240')
    root.title('简单加法器')
    
    lb1 = Label(root, text='请输入两个数,按下面两个按钮之一进行加法计算')
    lb1.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.1)
    inp1 = Entry(root)
    inp1.place(relx=0.1, rely=0.2, relwidth=0.3, relheight=0.1)
    inp2 = Entry(root)
    inp2.place(relx=0.6, rely=0.2, relwidth=0.3, relheight=0.1)
    
    # 方法-直接调用 run1()
    btn1 = Button(root, text='方法一', command=run1)
    btn1.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1)
    
    # 方法二利用 lambda 传参数调用run2()
    btn2 = Button(root, text='方法二', command=lambda: run2(inp1.get(), inp2.get()))
    btn2.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1)
    
    # 在窗体垂直自上而下位置60%处起,布局相对窗体高度40%高的文本框
    txt = Text(root)
    txt.place(rely=0.6, relheight=0.4)
    
    root.mainloop()
    

    3.3 单选按钮

    返回目录

    (Radiobutton)是为了响应故乡排斥的若干单选项的单击事件以触发运行自定义函数所设的,该控件排除具有共有属性外,还具有显示文本(text)、返回变量(variable)、返回值(value)、响应函数名(command)等重要属性。响应函数名“command=函数名”的用法与Button相同,函数名最后也要加括号。返回变量variable=var通常应预先声明变量的类型var=IntVar()或var=StringVar(),在所调用的函数中方可用var.get()方法获取被选中实例的value值。例如下面:
    在这里插入图片描述

    from tkinter import *
    def Mysel():
          dic = {0:'甲',1:'乙',2:'丙'}
          s = "您选了" + dic.get(var.get()) + "项"
          lb.config(text = s)
    
    root = Tk()
    root.title('单选按钮')
    lb = Label(root)
    lb.pack()
    
    var = IntVar()
    rd1 = Radiobutton(root,text="甲",variable=var,value=0,command=Mysel)
    rd1.pack()
    
    rd2 = Radiobutton(root,text="乙",variable=var,value=1,command=Mysel)
    rd2.pack()
    
    rd3 = Radiobutton(root,text="丙",variable=var,value=2,command=Mysel)
    rd3.pack()
    
    root.mainloop()
    

    3.4 复选框

    返回目录

    (Checkbutton) 是为了返回多个选项值的交互控件,通常不直接触发函数的执行。该控件除具有共有属性外,还具有显示文本(text)、返回变量(variable)、选中返回值(onvalue)和未选中默认返回值(offvalue)等重要属性。返回变量variable=var 通常可以预先逐项分别声明变量的类型var=IntVar() (默认)或 var=StringVar(), 在所调用的函数中方可分别调用 var.get()方法 取得被选中实例的 onvalue或offvalue值。复选框实例通常还可分别利用 select()、deselect()和 toggle() 方法对其进行选中、清除选中和反选操作。

    ○ 如下的例子: 利用复选框实现,单击OK,可以将选中的结果显示在标签上。效果如下:

    在这里插入图片描述
    ○ 方法:利用函数中的 if-else 分支实现多项显示

    from tkinter import *
    import tkinter
    
    def run():
         if(CheckVar1.get()==0 and CheckVar2.get()==0 and CheckVar3.get()==0 and CheckVar4.get()==0):
             s = '您还没选择任何爱好项目'
         else:
             s1 = "足球" if CheckVar1.get()==1 else ""
             s2 = "篮球" if CheckVar2.get() == 1 else ""
             s3 = "游泳" if CheckVar3.get() == 1 else ""
             s4 = "田径" if CheckVar4.get() == 1 else ""
             s = "您选择了%s %s %s %s" % (s1,s2,s3,s4)
         lb2.config(text=s)
    
    root = tkinter.Tk()
    root.title('复选框')
    lb1=Label(root,text='请选择您的爱好项目')
    lb1.pack()
    
    CheckVar1 = IntVar()
    CheckVar2 = IntVar()
    CheckVar3 = IntVar()
    CheckVar4 = IntVar()
    
    ch1 = Checkbutton(root,text='足球',variable = CheckVar1,onvalue=1,offvalue=0)
    ch2 = Checkbutton(root,text='篮球',variable = CheckVar2,onvalue=1,offvalue=0)
    ch3 = Checkbutton(root,text='游泳',variable = CheckVar3,onvalue=1,offvalue=0)
    ch4 = Checkbutton(root,text='田径',variable = CheckVar4,onvalue=1,offvalue=0)
    
    ch1.pack()
    ch2.pack()
    ch3.pack()
    ch4.pack()
    
    btn = Button(root,text="OK",command=run)
    btn.pack()
    
    lb2 = Label(root,text='')
    lb2.pack()
    root.mainloop()
    

    3.5 列表框 与 组合框

    3.5.1 列表框

    返回目录

    (Listbox) 可供用户单选或多选所列条目以形成人机交互。列表框控件的主要方法见下面的表:
    在这里插入图片描述
    执行自定义函数时,通常使用“实例名.surselection()” 或 “selected” 来获取选中项的位置索引。由于列表框实质上就是将Python 的列表类型数据可视化呈现,在程序实现时,也可直接对相关列表数据进行操作,然后再通过列表框展示出来,而不必拘泥于可视化控件的方法。看下面的一个例子:实现列表框的初始化、添加、插入、修改、删除和清空操作,如下:
    在这里插入图片描述

    from tkinter import *
    def ini():
          Lstbox1.delete(0,END)
          list_items = ["数学","物理","化学","语文","外语"]
          for item in list_items:
               Lstbox1.insert(END,item)
    
    def clear():
          Lstbox1.delete(0,END)
    
    def ins():
          if entry.get() != '':
              if Lstbox1.curselection() == ():
                  Lstbox1.insert(Lstbox1.size(),entry.get())
              else:
                  Lstbox1.insert(Lstbox1.curselection(),entry.get())
    
    def updt():
          if entry.get() != '' and Lstbox1.curselection() != ():
               selected=Lstbox1.curselection()[0]
               Lstbox1.delete(selected)
               Lstbox1.insert(selected,entry.get())
    
    def delt():
          if Lstbox1.curselection() != ():
               Lstbox1.delete(Lstbox1.curselection())
    
    root = Tk()
    root.title('列表框实验')
    root.geometry('320x240')
    
    frame1 = Frame(root,relief=RAISED)
    frame1.place(relx=0.0)
    
    frame2 = Frame(root,relief=GROOVE)
    frame2.place(relx=0.5)
    
    Lstbox1 = Listbox(frame1)
    Lstbox1.pack()
    
    entry = Entry(frame2)
    entry.pack()
    
    btn1 = Button(frame2,text='初始化',command=ini)
    btn1.pack(fill=X)
    
    btn2 = Button(frame2,text='添加',command=ins)
    btn2.pack(fill=X)
    
    btn3 = Button(frame2,text='插入',command=ins) # 添加和插入功能实质上是一样的
    btn3.pack(fill=X)
    
    btn4 = Button(frame2,text='修改',command=updt)
    btn4.pack(fill=X)
    
    btn5 = Button(frame2,text='删除',command=delt)
    btn5.pack(fill=X)
    
    btn6 = Button(frame2,text='清空',command=clear)
    btn6.pack(fill=X)
    
    root.mainloop()
    

    3.5.2 组合框

    返回目录

    (Combobox) 实质上是带文本框的上拉列表框,其功能也将是Python 的列表类型数据可视化呈现,并提供用户单选或多选所列条目以形成人机交互。在图形化界面设计时,由于其具有灵活的界面,因此往往比列表框更受喜爱。但该控件并不包含在 tkinter 模块中,而是与 TreeView、Progressbar、Separator等控件一同包含在tkinter 的子模块ttk中。如果使用该控件,应先与from tkinter import ttk 语句引用ttk子模块,然后创建组合框实例: 实例名=Combobox(根对象,[属性列表])
    指定变量var=StringVar(),并设置实例属性 textvariable = var,values=[列表…]。组合框控件常用方法有:获得所选中的选项值get()和获得所选中的选项索引current()。
    看下面的一个例子:实现四则运算计算器,将两个操作数分别填入两个文本框后,通过选择组合框中的算法触发运算,如下:
    在这里插入图片描述

    from tkinter.ttk import *
    
    def calc(event):
           a = float(t1.get())
           b = float(t2.get())
           dic = {0:a+b,1:a-b,2:a*b,3:a/b}
           c = dic[comb.current()]
           lbl.config(text=str(c))
    
    root = Tk()
    root.title('四则运算')
    root.geometry('320x240')
    
    t1 = Entry(root)
    t1.place(relx=0.1,rely=0.1,relwidth=0.2,relheight=0.1)
    
    t2 = Entry(root)
    t2.place(relx=0.5,rely=0.1,relwidth=0.2,relheight=0.1)
    
    var = StringVar()
    
    comb = Combobox(root,textvariable=var,values=['加','减','乘','除',])
    comb.place(relx=0.1,rely=0.5,relwidth=0.2)
    comb.bind('<<ComboboxSelected>>',calc)
    
    lbl=Label(root,text='结果')
    lbl.place(relx=0.5,rely=0.7,relwidth=0.2,relheight=0.3)
    
    root.mainloop()
    

    3.6 滑块

    返回目录

    (Scale) 是一种 直观地进行数值输入的交互控件,其主要属性见下表:
    在这里插入图片描述
    滑块控件实例的主要方法比较简单,有 get()set(值),分别为取值和将滑块设在某特定值上。滑块实例也可绑定鼠标左键释放事件<ButtoonRelease-1>,并在执行函数中添加参数event来实现事件响应。
    例如:在一个窗体上设计一个200像素宽的水平滑块,取值范围为1.0~5.0,分辨精度为0.05,刻度间隔为 1,用鼠标拖动滑块后释放鼠标可读取滑块值并显示在标签上。效果如下:
    在这里插入图片描述

    from tkinter  import  *
    
    def show(event):
          s = '滑块的取值为' + str(var.get())
          lb.config(text=s)
    
    root = Tk()
    root.title('滑块实验')
    root.geometry('320x180')
    var=DoubleVar()
    scl = Scale(root,orient=HORIZONTAL,length=200,from_=1.0,to=5.0,label='请拖动滑块',tickinterval=1,resolution=0.05,variable=var)
    scl.bind('<ButtonRelease-1>',show)
    scl.pack()
    
    lb = Label(root,text='')
    lb.pack()
    
    root.mainloop()
    

    3.7 菜单

    返回目录

    (Menu)用于可视化地为一系列的命令分组,从而方便用户找到和触发执行这些命令。这里Menu所实例化别的主要是菜单,其通式为:

    菜单实例名=Menu(根窗体)
    菜单分组1=Menu(菜单实例名)
    菜单实例名.add_cascade(<label=菜单分组1 显示文本>,<menu=菜单分组1>)
    菜单分组1.add_command(<label=命令1文本>,<command=命令1函数名>)
    

    其中较为常见的方法有:add_cascade()add_command()add_separator(),分别用于添加一个菜单分组、添加一条菜单命令和添加一条分割线。
    利用Menu控件也可以创建快捷菜单(又称为上下文菜单)。通常需要右击弹出的控件实例绑定鼠标右击响应事件,并指向一个捕获event参数的自定义函数,在该自定义函数中,将鼠标的触发位置event.x_root 和 event.y_root以post()方法传给菜单。
    例子: 仿照window自带的“记事本”中的文件和编辑 菜单,实现在主菜单个快捷菜单上触发菜单命令,并相应改变窗体上的标签的文本内容。效果如下:
    在这里插入图片描述

    from tkinter import *
    
    def new():
         s = '新建'
         lb1.config(text=s)
    
    def ope():
         s = '打开'
         lb1.config(text=s)
    
    def sav():
         s = '保存'
         lb1.config(text=s)
    
    def cut():
         s = '剪切'
         lb1.config(text=s)
    
    def cop():
         s = '复制'
         lb1.config(text=s)
    
    def pas():
         s = '粘贴'
         lb1.config(text=s)
    
    def popupmenu(event):
         mainmenu.post(event.x_root,event.y_root)
    
    root = Tk()
    root.title('菜单实验')
    root.geometry('320x240')
    
    lb1 = Label(root,text='显示信息',font=('黑体',32,'bold'))
    lb1.place(relx=0.2,rely=0.2)
    
    mainmenu = Menu(root)
    menuFile = Menu(mainmenu)  # 菜单分组 menuFile
    mainmenu.add_cascade(label="文件",menu=menuFile)
    menuFile.add_command(label="新建",command=new)
    menuFile.add_command(label="打开",command=ope)
    menuFile.add_command(label="保存",command=sav)
    menuFile.add_separator()  # 分割线
    menuFile.add_command(label="退出",command=root.destroy)
    
    menuEdit = Menu(mainmenu)  # 菜单分组 menuEdit
    mainmenu.add_cascade(label="编辑",menu=menuEdit)
    menuEdit.add_command(label="剪切",command=cut)
    menuEdit.add_command(label="复制",command=cop())
    menuEdit.add_command(label="粘贴",command=pas())
    
    root.config(menu=mainmenu)
    root.bind('Button-3',popupmenu) # 根窗体绑定鼠标右击响应事件
    root.mainloop()
    

    3.8 子窗体

    返回目录

    用Toplevel可新建一个显示在最前面的子窗体,其通式为: 字体实例名=Toplevel(根窗体),子窗体与根窗体类似,也可设置title、geomerty等属性,并在画布上布局其他控件。如下的例子:在根窗体上创建菜单,触发创建一个新的窗体
    在这里插入图片描述

    from tkinter import *
    
    def newwind():
          winNew = Toplevel(root)
          winNew.geometry('320x240')
          winNew.title('新窗体')
          lb2 = Label(winNew,text='我在新窗体上')
          lb2.place(relx=0.2,rely=0.2)
          btClose=Button(winNew,text='关闭',command=winNew.destroy)
          btClose.place(relx=0.7,rely=0.5)
    
    root = Tk()
    root.title('新建窗体实验')
    root.geometry('320x240')
    
    lb1 = Label(root,text='主窗体',font=('黑体',32,'bold'))
    lb1.place(relx=0.2,rely=0.2)
    
    mainmenu = Menu(root)
    menuFile = Menu(mainmenu)
    mainmenu.add_cascade(label='菜单',menu=menuFile)
    menuFile.add_command(label='新窗体',command=newwind)
    menuFile.add_separator()
    menuFile.add_command(label='退出',command=root.destroy)
    
    root.config(menu=mainmenu)
    root.mainloop()
    

    关闭窗体程序运行的方法通常用 destory(),而不建议用 quit()。用Toplevel 所创建的子窗体是非模式(Modeless)的窗体,虽然初建时子窗体在最前面,但根窗体上的控件实例也是可以被操作的。

    3.9 模式对话框(Modal)

    返回目录

    是相对于前面介绍的非模式窗体而言的,所弹出的对话框必须应答,在关闭之前无法操作其后面的其他窗体。常见的模式对话框有消息对话框、输入对话框、文件选择对话框、颜色选择对话框等。

    3.9.1 交互对话框

    返回目录

    (一)、消息对话框: 引用 tkinter.messagebox 包,可使用消息对话框函数。执行这些函数,可弹出模式消息对话框,并根据用户的响应但会一个布尔值。其通式为:

    消息对话框函数(<title=标题文本>,<message=消息文本>,[其他参数])
    

    看下面的例子:单击按钮,弹出确认取消对话框,并将用户回答显示在标签中。效果如下:
    在这里插入图片描述

    from tkinter import *
    import tkinter.messagebox
    
    def xz():
        answer=tkinter.messagebox.askokcancel('请选择','请选择确定或取消')
        if answer:
            lb.config(text='已确认')
        else:
            lb.config(text='已取消')
    
    root = Tk()
    
    lb = Label(root,text='')
    lb.pack()
    btn=Button(root,text='弹出对话框',command=xz)
    btn.pack()
    root.mainloop()
    

    (二)、输入对话框: 引用tkinter.simpledialog包,可弹出输入对话框,用以接收用户的简单输入。输入对话框常用 askstring()、askfloat()和askfloat() 三种函数,分别用于接收字符串、整数和浮点数类型的输入。
    如下面的例子:单击按钮,弹出输入对话框,接收文本输入显示在窗体的标签上。如下:
    在这里插入图片描述

    from tkinter.simpledialog import *
    
    def xz():
        s=askstring('请输入','请输入一串文字')
        lb.config(text=s)
    
    root = Tk()
    
    lb = Label(root,text='')
    lb.pack()
    btn=Button(root,text='弹出输入对话框',command=xz)
    btn.pack()
    root.mainloop()
    

    3.9.2 文件选择对话框

    返回目录

    引用tkinter.filedialog包,可弹出文件选择对话框,让用户直观地选择一个或一组文件,以供进一步的文件操作。常用的文件选择对话框函数有 askopenfilename()、askopenfilenames()和asksaveasfilename(),分别用于进一步打开一个文件、一组文件和保存文件。其中,askopenfilename()和asksaveasfilenamme()函数的返回值类型为包含文件路径的文件名字符串,而askopenfilenames()函数的返回值类型为元组。
    例如:单击按钮,弹出文件选择对话框(“打开”对话框),并将用户所选择的文件路径和文件名显示在窗体的标签上。如下
    在这里插入图片描述

    from tkinter import *
    import tkinter.filedialog
    
    def xz():
        filename=tkinter.filedialog.askopenfilename()
        if filename != '':
             lb.config(text='您选择的文件是'+filename)
        else:
             lb.config(text='您没有选择任何文件')
    
    root = Tk()
    
    lb = Label(root,text='')
    lb.pack()
    btn=Button(root,text='弹出文件选择对话框',command=xz)
    btn.pack()
    root.mainloop()
    

    3.9.3、颜色选择对话框

    返回目录

    引用tkinter.colorchooser包,可使用 askcolor()函数弹出模式颜色选择对话框,让用户可以个性化地设置颜色属性。该函数的返回形式为包含RGB十进制浮点元组和RGB十六进制字符串的元组类型,例如:“((135.527343.52734375,167.65234375,186.7265625)),’#87a7ba’”。通常,可将其转换为字符串类型后,再截取以十六进制数表示的RGB颜色字符串用于为属性赋值。
    举例:单击按钮,弹出颜色选择对话框,并将用户所选择的颜色设置为窗体上标签的背景颜色,如下:
    在这里插入图片描述

    from tkinter import *
    import tkinter.colorchooser
    
    def xz():
        color=tkinter.colorchooser.askcolor()
        colorstr=str(color)
        print('打印字符串%s 切掉后=%s' % (colorstr,colorstr[-9:-2]))
        lb.config(text=colorstr[-9:-2],background=colorstr[-9:-2])
    
    root = Tk()
    
    lb = Label(root,text='请关注颜色的变化')
    lb.pack()
    btn=Button(root,text='弹出颜色选择对话框',command=xz)
    btn.pack()
    root.mainloop()
    

    四、事件响应

    返回目录

    用tkinter 可将用户事件与自定义函数绑定,用键盘或鼠标的动作事件来响应触发自定义函数的执行。其通式为:

    控件实例.bind(<事件代码>,<函数名>)
    

    其中,事件代码通常以半角小于号“<”和大于号“>” 界定,包括事件和按键等 2~3个部分,它们之间用减号分隔,常见事件代码见下表:
    在这里插入图片描述
    例如,将框架控件实例frame 绑定鼠标右键单击事件,调用自定义函数 myfunc()可表示为"frame.bind(’’,myfunc)",注意: myfunc后面没有括号。将控件实例绑定到键盘事件和部分光标不落在具体控件实例上的鼠标事件时,还需要设置该实例执行focus_set() 方法获得焦点,才能对事件持续响应。例如: frame.focus_set()。所调用的自定义函数若需要利用鼠标或键盘的响应值,可将event作为参数,通过event的属性获取。event的属性见下表:
    在这里插入图片描述
    在这里插入图片描述

    from tkinter import *
    
    def show(event):
    s=event.keysym
    lb.config(text=s)
    
    root=Tk()
    root.title('按键实验')
    root.geometry('200x200')
    lb=Label(root,text='请按键',font=('黑体',48))
    lb.bind('<Key>',show)
    lb.focus_set()
    lb.pack()
    root.mainloop()
    

    补充:

    五、背景图片

    1、添加背景

    返回目录

    #插入文件图片
    import tkinter as tk
    
    root = tk.Tk()
    
    #创建一个标签类, [justify]:对齐方式
    textLabel = tk.Label(root,text="你在右边会看到一个图片,\n我在换个行",
    justify = tk.LEFT)#左对齐
    textLabel.pack(side=tk.LEFT)#自动对齐,side:方位
    
     
    
    #创建一个图片管理类
    photo = tk.PhotoImage(file="18.png")#file:t图片路径
    imgLabel = tk.Label(root,image=photo)#把图片整合到标签类中
    imgLabel.pack(side=tk.RIGHT)#自动对齐
    
    
    tk.mainloop()
    

    在这里插入图片描述

    返回目录

    import tkinter as tk
    
    root = tk.Tk()
    
    
    #增加背景图片
    photo = tk.PhotoImage(file="背景.png")
    theLabel = tk.Label(root,
             text="我是内容,\n请你阅读",#内容
             justify=tk.LEFT,#对齐方式
             image=photo,#加入图片
             compound = tk.CENTER,#关键:设置为背景图片
             font=("华文行楷",20),#字体和字号
             fg = "white")#前景色
    theLabel.pack()
    
     
    
    tk.mainloop()
    

    在这里插入图片描述

    返回目录

    #插入文件图片
    import tkinter as tk
    
    root = tk.Tk()
    
    frame1 = tk.Frame(root)#这是上面的框架
    frame2 = tk.Frame(root)#这是下面的框架
    
    
    var = tk.StringVar()#储存文字的类
    var.set("你在右边会看到一个图片,\n我在换个行")#设置文字
    
    #创建一个标签类, [justify]:对齐方式,[frame]所属框架
    textLabel = tk.Label(frame1,textvariable=var,
             justify = tk.LEFT)#显示文字内容 
    textLabel.pack(side=tk.LEFT)#自动对齐,side:方位
    
     
    
    #创建一个图片管理类
    photo = tk.PhotoImage(file="18.png")#file:t图片路径
    imgLabel = tk.Label(frame1,image=photo)#把图片整合到标签类中
    imgLabel.pack(side=tk.RIGHT)#自动对齐
    
    
    def callback():#触发的函数
      var.set("你还真按了")#设置文字
    
    #[frame]所属框架 ,text 文字内容 command:触发方法
    theButton = tk.Button(frame2,text="我是下面的按钮",command=callback)
    theButton.pack()#自动对齐
    
     
    
    frame1.pack(padx=10,pady=10)#上框架对齐
    frame2.pack(padx=10,pady=10)#下框架对齐
    
    
    tk.mainloop()
    

    在这里插入图片描述
    在这里插入图片描述

    返回目录

    六、打开摄像头,显示

    效果:
    在这里插入图片描述
    代码:

      from tkinter import *
        import cv2
        from PIL import Image,ImageTk
        
        
        def take_snapshot():
            print("有人给你点赞啦!")
        
        def video_loop():
            success, img = camera.read()  # 从摄像头读取照片
            if success:
                cv2.waitKey(100)
                cv2image = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)#转换颜色从BGR到RGBA
                current_image = Image.fromarray(cv2image)#将图像转换成Image对象
                imgtk = ImageTk.PhotoImage(image=current_image)
                panel.imgtk1 = imgtk
                panel.config(image=imgtk)
                root.after(1, video_loop)
        
        camera = cv2.VideoCapture(0)    #摄像头
        
        root = Tk()
        root.title("opencv + tkinter")
        #root.protocol('WM_DELETE_WINDOW', detector)
        
        
        panel = Label(root)  # initialize image panel
        panel.pack(padx=10, pady=10)
        # root.config(cursor="arrow")
        btn = Button(root, text="点赞!", command=take_snapshot)
        btn.pack(fill="both", expand=True, padx=10, pady=10)
        
        video_loop()
        
        root.mainloop()
        # 当一切都完成后,关闭摄像头并释放所占资源
        camera.release()
        cv2.destroyAllWindows()
    

    感谢前辈:
    https://www.jianshu.com/p/91844c5bca78
    https://www.cnblogs.com/banzhen/p/7427201.html
    https://blog.csdn.net/a1_a1_a/article/details/79981788

    展开全文
  • 主要讲的tkinter的现代会界面,也就是着重于ttk的运用
  • python之Tkinter使用详解

    千次阅读 2021-06-06 13:24:59
    1.1、Tkinter是什么 Tkinter 是使用 python 进行窗口视窗设计的模块。Tkinter模块(“Tk 接口”)是Python的标准Tk GUI工具包的接口。作为 python 特定的GUI界面,是一个图像的窗口,tkinter是python自带的,可以编辑...
  • Python中Tkinter 图形化界面设计(详细教程

    千次阅读 多人点赞 2020-12-08 17:41:41
    Python-Tkinter 图形化界面设计(详细教程)一、图形化界面设计的基本理解二、 窗体控件布局2.1 根窗体呈现示例2.2 tkinter 常用控件2.2.1常用控件2.2.2 控件的共同属性2.3 控件布局2.3.1 place() 使用方法三、...
  • tkinter教程

    2018-12-19 19:30:12
    超级详细的tkinker教程Tkinter 是使用 python 进行窗口视窗设计的模块. 简单的构造, 多平台, 多系统的兼容性, 能让它成为让你快速入门定制窗口文件的好助手. 它在 python 窗口视窗模块中是一款简单型的. 所以用来...
  • 主要介绍了python tkinter事件绑定,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • Python GUI之tkinter教程

    千次阅读 多人点赞 2020-06-21 11:53:18
    tkinter的简介 tkinter 是 Python 的标准 GUI 库。它基于 Tk 工具包,该工具包最初是为工具命令语言(Tool Command Language,Tcl)设计的。Tk 普及后,被移植到很多其他的脚本语言中,包括 Perl,Ruby 和 Python。...
  • Tkinter简明教程.pdf,该pdf中详细讲述了tkinter的用法和介绍。
  • tkinter库最全使用教程

    万次阅读 多人点赞 2020-05-05 08:04:43
    标准库tkinter常用功能 ①导入第标准库(tkinter为python标准库无需安装) from tkinter import * ②窗口的创建和设置 窗口的创建和设置方法 注释 root=Tk() 生成主窗口 root.geometry(‘250x250’) 改变...
  • 将Matplotlib绘制的图显示到Tkinter中(详细教程

    万次阅读 多人点赞 2019-06-13 20:56:38
    root = tkinter.Tk() # 创建tkinter的主窗口 root.title("在tkinter中使用matplotlib") f = Figure(figsize=(5, 4), dpi=100) a = f.add_subplot(111) # 添加子图:1行1列第1个 # 生成用于绘sin图的数据 x = np.a...
  • Python GUI 图形化界面tkinter 做课设需要用到GUI图形化界面,找到了这篇博客 https://www.cnblogs.com/shwee/p/9427975.html#D3 可以说写的非常详细,而且每个组件都有示例,最后还有一个综合实例。非常适合作为...
  • 本文将详细介绍 Treeview 作为表格和作为树的使用方法,并提供具有源码的示例。 tkinter Treeview 控件的使用方法 创建 Treeview 控件 Treeview 参数解读 作为表格使用 Treeview 作为树使用 Treeview Treeview ...
  • 主要为大家详细介绍了python使用tkinter库实现五子棋游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • Python GUI之tkinter窗口视窗教程大集合

    千次阅读 多人点赞 2019-05-13 09:26:29
    Python GUI之tkinter窗口视窗教程大集合一、前言二、Tkinter是什么三、Tkinter 控件详细介绍1. Tkinter 模块元素简要说明2. 常用窗口部件及简要说明:四、动手实践学习1. 创建主窗口及Label部件(标签)创建使用2. ...
  • 与pyqt5相比,tkinter无疑是更简单的选择,在对图形化界面没有太高要求的情况下,个人十分推荐选择tkinter。当然,如果你本身具备了一定Qt的使用经验,转移到pyqt并不会很复杂。而且与tkinter相比,pyqt可以用...
  • 三、tkinter常见控件的特征属性 3.1 文本输入和输出相关控件 3.1.1 标签(Label)和 消息(Message) 文本的输入与输出控件通常包括:标签(Label)、消息(Message)、输入框(Entry)、文本框(Text)。他们除了...
  • python GUI编程(Tkinter)

    2021-03-05 13:19:09
    python提供了多个图形开发界面的库,几个常用Python GUI库如下:TkinterTkinter模块("Tk 接口")是Python的标准Tk GUI工具包的接口.Tk和Tkinter可以在大多数的Unix平台下使用,同样可以应用在Windows和Macintosh...
  • tkinter教程详细 python里面专门做GUI的,不是扫描版
  • python之tkinter窗口 python之tkinter窗口 控件的用法:  Label : 标签  Frame:框架,就是一个容器. Entry:单行文本输入域 Text: Button:按钮部件是一个标准的Tkinter窗口部件,用实现各种按钮。按钮能够包含...
  • tkinter库入门详细教程(二):输入框和文本显示框

    万次阅读 多人点赞 2018-07-31 10:17:51
    更多内容请看tkinter库入门详细教程(三) 如上图所示,在输入窗口输入字符串后,选择在‘在光标处插入’或‘在末尾处插入’,文本显示框能显示出相应内容。 源代码: import tkinter as tk # 设置窗口 window...
  • 一、前言二、Tkinter 是什么三、Tkinter 控件详细介绍1. Tkinter 模块元素简要说明2. 常用窗口部件及简要说明:四、动手实践学习1. 创建主窗口及Label部件(标签)创建使用2. Button窗口部件3. Entry窗口部件4. Text...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,843
精华内容 737
关键字:

tkinter详细教程