Loading

python程序交互界面之GUI窗体程序 Tkinter

关于Tkinter

Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里。Tk8.0 的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中。

Tkinter模块("Tk 接口")是Python的标准Tk GUI工具包的接口。作为 python 特定的GUI界面,是一个图像的窗口,tkinter是python 自带的,可以编辑的GUI界面,我们可以用GUI 实现很多直观的功能,比如想开发一个计算器,如果只是一个程序输入,输出窗口的话,是没用用户体验的。所有开发一个图像化的小窗口,就是必要的。

对于稍有GUI编程经验的人来说,Python的Tkinter界面库是非常简单的。python的GUI库非常多,选择Tkinter,一是最为简单,二是自带库,不需下载安装,随时使用,三则是从需求出发,Python作为一种脚本语言,一种胶水语言,一般不会用它来开发复杂的桌面应用,它并不具备这方面的优势,使用Python,可以把它作为一个灵活的工具,而不是作为主要开发语言,那么在工作中,需要制作一个小工具,肯定是需要有界面的,不仅自己用,也能分享别人使用,在这种需求下,Tkinter是足够胜任的!

Tkinter 编程

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

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

import tkinter

Tkinter 组件

Tkinter的提供各种控件,如按钮,标签和文本框,一个GUI应用程序中使用。这些控件通常被称为控件或者部件。

目前有15种Tkinter的部件。我们提出这些部件以及一个简短的介绍,在下面的表:

控件 描述
Button 按钮控件;在程序中显示按钮。
Canvas 画布控件;显示图形元素如线条或文本
Checkbutton 多选框控件;用于在程序中提供多项选择框
Entry 输入控件;用于显示简单的文本内容
Frame 框架控件;在屏幕上显示一个矩形区域,多用来作为容器
Label 标签控件;可以显示文本和位图
Listbox 列表框控件;在Listbox窗口小部件是用来显示一个字符串列表给用户
Menubutton 菜单按钮控件,用于显示菜单项。
Menu 菜单控件;显示菜单栏,下拉菜单和弹出菜单
Message 消息控件;用来显示多行文本,与label比较类似
Radiobutton 单选按钮控件;显示一个单选的按钮状态
Scale 范围控件;显示一个数值刻度,为输出限定范围的数字区间
Scrollbar 滚动条控件,当内容超过可视化区域时使用,如列表框。.
Text 文本控件;用于显示多行文本
Toplevel 容器控件;用来提供一个单独的对话框,和Frame比较类似
Spinbox 输入控件;与Entry类似,但是可以指定输入范围值
PanedWindow PanedWindow是一个窗口布局管理的插件,可以包含一个或者多个子控件。
LabelFrame labelframe 是一个简单的容器控件。常用与复杂的窗口布局。
tkMessageBox 用于显示你应用程序的消息框。

标准属性

标准属性也就是所有控件的共同属性,如大小,字体和颜色等等。

属性 描述
Dimension 控件大小;
Color 控件颜色;
Font 控件字体;
Anchor 锚点;
Relief 控件样式;
Bitmap 位图;
Cursor 光标;

实践1:制作一个BMI 计算器GUI程序

编写一个简单的界面,用户输入体重、身高,点击计算按钮,生成身体质量指数,简称体质数

示例代码

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import tkinter as tk
from tkinter import ttk # 主体控件命名模块


class BMIView(tk.Frame):
    def __init__(self,parent,*args,**kwargs):
        super().__init__(parent,*args,**kwargs) # parent 指的是当前这个控件容器将会依附在哪个容器或者窗体之上
        self.body_weight = tk.DoubleVar()
        self.height = tk.DoubleVar()
        self.bmi = tk.StringVar()

        lbl_body_weight = ttk.Label(self,text="体重(Kg):")
        entry_body_weight = ttk.Entry(self,textvariable=self.body_weight)

        lbl_height = ttk.Label(self,text="身高(m):")
        entry_height = ttk.Entry(self,textvariable=self.height)

        btn_calculate = ttk.Button(self,text="计算",command=self.on_calculate)
        lbl_bmi = ttk.Label(self,textvariable=self.bmi,font=("Microsoft Yahei",64),wraplength=480)

        lbl_body_weight.grid(row=0,column=0,sticky=tk.W)
        entry_body_weight.grid(row=0,column=1,sticky=(tk.W+tk.E))
        lbl_height.grid(row=0,column=2,sticky=(tk.W+tk.E))
        entry_height.grid(row=0,column=3,sticky=(tk.W+tk.E))
        btn_calculate.grid(row=0,column=4,sticky=(tk.E))
        lbl_bmi.grid(row=1,column=0,columnspan=5) # columnspan=5 合并5个单元格

        self.columnconfigure(1,weight=1)
        self.columnconfigure(3,weight=1)


    def on_calculate(self):
        bmi = self.body_weight.get() / (self.height.get() ** 2)
        print('bmi:',bmi)
        self.bmi.set(f"{bmi:.1f}")


class BMIApplication(tk.Tk):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.title("BMI 计算器")
        self.geometry("640x180")
        self.resizable(width=False,height=False)

        BMIView(self).grid(sticky=(tk.E+tk.N+tk.W+tk.S))

        self.columnconfigure(0,weight=1)


if __name__ == '__main__':
    app = BMIApplication()
    app.mainloop()


测试功能:

实践2:制作一个简单登录的GUI程序

输入用户名、密码,点击登录

AC1:输入正确用户名、密码,点击登录,弹窗提示登录成功

AC2:输入错误用户名或密码,点击登录,弹窗提示登录异常

# !/usr/bin/env python3
# -*- coding:utf-8 -*-


"""使用Entry组件的基本用法,使用面向对象的方式"""
import tkinter as tk
from tkinter import messagebox

class Application(tk.Frame):
    def __init__(self,master=None):
        super().__init__(master)  # super()代表的是父类的定义,而不是父类对象
        self.master = master
        self.pack()

        self.createWidget()

    def createWidget(self):

        global photo  # 把photo声明成全局变量。如果是局部变量,本方法执行完毕后,图像对象销毁,窗口显示不出来
        photo = tk.PhotoImage(file="imge/logo.png")
        self.label03 = tk.Label(self, image=photo)
        self.label03.pack()

        """创建界面登录的组件"""
        self.label01 = tk.Label(self,text="用户名")
        self.label01.pack()

        # StringVar变量绑定到指定组件
        # StringVar变量的值发生变化,组件内容也变化
        # 组件内容发生变化,StringVar变量的值也发生变化
        v1 = tk.StringVar()
        self.entry01 = tk.Entry(self,textvariable=v1)
        self.entry01.pack()
        v1.set("admin")

        """创建密码框"""
        self.label02 = tk.Label(self, text="密码")
        self.label02.pack()

        v2 = tk.StringVar()
        self.entry02 = tk.Entry(self, textvariable=v2,show="*")
        self.entry02.pack()

        self.btn01 = tk.Button(self, text="登录", command=self.login)
        self.btn01.pack()

    def login(self):
        username = self.entry01.get()
        pwd = self.entry02.get()
        if username == "admin" and pwd == "123456":
            messagebox.showinfo("登录系统","登录成功!欢迎开始学习!")
        else:
            messagebox.showinfo("登录系统", "账号或密码错误,请重新输入")

root = tk.Tk()

root.geometry("400x300+600+400")
root.title("测试Entry")
app = Application(master=root)

if __name__ == '__main__':
    root.mainloop()

实践3:操作TEXT的GUI程序

# !/usr/bin/env python3
# -*- coding:utf-8 -*-


"""使用Text组件的基本用法,使用面向对象的方式"""
import tkinter as tk
import webbrowser

class Application(tk.Frame):
    def __init__(self,master=None):
        super().__init__(master)  # super()代表的是父类的定义,而不是父类对象
        self.master = master
        self.pack()

        self.createWidget()

    def createWidget(self):
        self.w1 = tk.Text(root,width=40,height=12,bg="gray")
        # 宽度20个字母(10个汉字),高度一个行高
        self.w1.pack()

        self.w1.insert(1.0,"0123456789\nabcdefghijklmn")
        self.w1.insert(2.3,"锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦\n")

        tk.Button(self,text="重复插入文本",command=self.insertText).pack(side="left")
        tk.Button(self,text="返回文本",command=self.returnText).pack(side="left")
        tk.Button(self,text="添加图片",command=self.addImage).pack(side="left")
        tk.Button(self,text="添加组件",command=self.addWidget).pack(side="left")
        tk.Button(self,text="通过tag精确控制文本",command=self.testTag).pack(side="left")

    def insertText(self):
        # INSERT索引表示在光标处插入
        self.w1.insert(tk.INSERT,' test ')
        # END索引表示在最后插入
        self.w1.insert(tk.END,'[sxt]')

    def returnText(self):
        # Indexes(索引)是用来指向Text组件中文本的位置,Text的组件索引也是对应实际字符之间得位置
        # 核心:行号以1开始,列号以0开始
        print(self.w1.get(1.2,1.6))
        self.w1.insert(1.8," test2 ")
        print("所有文本内容:\n"+self.w1.get(1.0,tk.END))

    def addImage(self):
        self.photo = tk.PhotoImage(file="imge/logo.png")
        self.w1.image_create(tk.END,image=self.photo)

    def addWidget(self):
        b1 = tk.Button(self.w1,text="测试TEXT")
        # 在text创建组件的命令
        self.w1.window_create(tk.INSERT,window=b1)

    def testTag(self):
        self.w1.delete(1.0,tk.END)
        self.w1.insert(tk.INSERT,"good good study,day day up!\n前端开发\n后端开发\n测试设计")
        self.w1.tag_add("good",1.0,1.9)
        self.w1.tag_config("good",background="yellow",foreground="red")
        self.w1.tag_add("baidu",4.0,4.2)
        self.w1.tag_config("baidu",underline=True)
        self.w1.tag_bind("baidu","<Button-1>",self.webshow)

    def webshow(self,event):
        webbrowser.open("https://www.baidu.com")


root = tk.Tk()

root.geometry("500x250+600+400")
root.title("测试TEXT")
app = Application(master=root)

if __name__ == '__main__':
    root.mainloop()

posted @ 2021-09-04 14:36  Binzichen  阅读(4160)  评论(0编辑  收藏  举报