python-09( Tk图形用户界面(GUI))

什么是Tkinter

Tkinter 是使用 python 进行窗口视窗设计的模块。Tkinter模块(“Tk 接口”)是Python的标准Tk GUI工具包的接口。作为 python 特定的GUI界面,是一个图像的窗口,tkinter是python自带的,可以编辑的GUI界面,用来入门,熟悉窗口视窗的使用,非常有必要。

提供tk支持的模块包括:

模块说明
tkinterTK主模块
tkinter.colorchooser让用户选择颜色的对话框。
tkinter.commondialog其他模块定义的对话框的基类。
tkinter.filedialog允许用户指定文件的通用对话框,用于打开或保存文件。
tkinter.font帮助操作字体的工具。
tkinter.messagebox访问标准的 Tk 对话框。
tkinter.scrolledtext内置纵向滚动条的文本组件。
tkinter.simpledialog基础对话框和一些便捷功能。
tkinter.ttkTk 8.5中引入的主题小部件集,为tkinter主模块中的许多经典小部件提供了现代替代品。

Tkinter基本运用(记得导包

Tkinter创建窗口

首先,我们导入tkinter的库。

# 导入tkinter库 
from tkinter import *
# 创建一个窗口
window = Tk()
# 设置窗口标题
window.title("窗口标题栏")
# 设置窗口显示尺寸
window.geometry("500x400")
# 进入消息循环,显示窗口
window.mainloop()

结果如图所示:

窗口居中显示:

# 获取屏幕的宽度和高度
screenwidth = window.winfo_screenwidth()
screenheight = window.winfo_screenheight()

# 计算窗口左上角的坐标,使窗口居中显示
x = int(screenwidth / 2 - 500 / 2)  # 窗口左上角的 x 坐标
y = int(screenheight / 2 - 400 / 2)  # 窗口左上角的 y 坐标

# 设置窗口大小和位置
size = '{}x{}+{}+{}'.format(500, 400, x, y)  # 窗口的大小和位置
window.geometry(size)  # 设置窗口的几何属性,即大小和位置

 

Tkinter基本控件

Tkinter的提供各种控件,如按钮,标签和文本框等,这些控件通常被称为控件或者部件。目前 Tkinter中常用的 15 个控件,如下所示:

控件类型控件名称控件作用
Button按钮点击按钮时触发/执行一些事件(函数)
Canvas画布提供绘制图,比如直线、矩形、多边形等
Checkbutton复选框多项选择按钮,用于在程序中提供多项选择框
Entry文本框输入框用于接收单行文本输入
Frame框架(容器)控件定义一个窗体(根窗口也是一个窗体),用于承载其他控件,即作为其他控件的容器
Label标签控件用于显示单行文本或者图片
LabelFrame容器控件一个简单的容器控件,常用于复杂的窗口布局。
Listbox列表框控件以列表的形式显示文本
Menu菜单控件菜单组件(下拉菜单和弹出菜单)
Menubutton菜单按钮控件用于显示菜单项
Message信息控件用于显示多行不可编辑的文本,与 Label控件类似,增加了自动分行的功能
messageBox消息框控件定义与用户交互的消息对话框
OptionMenu选项菜单下拉菜单
PanedWindow窗口布局管理组件为组件提供一个框架,允许用户自己划分窗口空间
Radiobutton单选框单项选择按钮,只允许从多个选项中选择一项
Scale进度条控件定义一个线性“滑块”用来控制范围,可以设定起始值和结束值,并显示当前位置的精确值
Spinbox高级输入框Entry 控件的升级版,可以通过该组件的上、下箭头选择不同的值
Scrollbar滚动条默认垂直方向,鼠标拖动改变数值,可以和 Text、Listbox、Canvas等控件配合使用
Text多行文本框接收或输出多行文本内容
Toplevel子窗口在创建一个独立于主窗口之外的子窗口,位于主窗口的上一层,可作为其他控件的容器

后续我们将进行部分组件的案例演示。

标签

Python Tkinter 标签控件(Label)指定的窗口中显示的文本和图像。

属性名称说明
anchor控制文本(或图像)在 Label 中显示的位置(方位),通过方位的英文字符串缩写(n、ne、e、se、s、sw、w、nw、center)实现定位,默认为居中(center)
bg用来设置背景色
bd即 borderwidth 用来指定 Label 控件的边框宽度,单位为像素,默认为 2 个像素
bitmap指定显示在 Label 控件上的位图,若指定了 image 参数,则该参数会被忽略
compound控制 Lable 中文本和图像的混合模式,若选项设置为 CENTER,则文本显示在图像上,如果将选项设置为 BOTTOM、LEFT、RIGHT、TOP,则图像显示在文本旁边。
cursor指定当鼠标在 Label 上掠过的时候,鼠标的的显示样式,参数值为 arrow、circle、cross、plus
disableforeground指定当 Label 设置为不可用状态的时候前景色的颜色
font指定 Lable 中文本的 (字体,大小,样式)元组参数格式,一个 Lable 只能设置一种字体
fg设置 Label 的前景色
height/width设置 Lable 的高度/宽度,如果 Lable 显示的是文本,那么单位是文本单元,如果 Label 显示的是图像,那么单位就是像素,如果不设置,Label 会自动根据内容来计算出标签的高度
highlightbackground当 Label 没有获得焦点的时候高亮边框的颜色,系统的默认是标准背景色
highlightcolor指定当 Lable 获得焦点的话时候高亮边框的颜色,系统默认为0,不带高亮边框
image指定 Label 显示的图片,一般是 PhotoImage、BitmapImage 的对象
justify表示多行文本的对齐方式,参数值为 left、right、center,注意文本的位置取决于 anchor 选项
padx/padypadx 指定 Label 水平方向上的间距(即内容和边框间),pady 指定 Lable 水平方向上的间距(内容和边框间的距离)
relief指定边框样式,默认值是 "flat",其他参数值有 "groove"、"raised"、"ridge"、"solid"或者"sunken"
state该参数用来指定 Lable 的状态,默认值为"normal"(正常状态),其他可选参数值有"active"和"disabled"
takefocus默认值为False,如果是 True,表示该标签接受输入焦点
text用来指定 Lable 显示的文本,注意文本内可以包含换行符
underline给指定的字符添加下划线,默认值为 -1 表示不添加,当设置为 1 时,表示给第二个文本字符添加下划线。
wraplength将 Label 显示的文本分行,该参数指定了分行后每一行的长度,默认值为 0

基本案例:

# 创建一个标签
lb = Label(window, text="书本名称:", font=("宋体", 12))
# 设置标签在窗口的显示位置
lb.place(x=10, y=10)

输入框

Entry 控件是 Tkinter GUI 编程中的基础控件之一,它的作用就是允许用户输入内容,从而实现 GUI 程序与用户的交互,比如当用户登录软件时,输入用户名和密码,此时就需要使用 Entry 控件。

基本属性:

属性名称说明
exportselection默认情况下,如果在输入框中选中文本会复制到粘贴板,如果要忽略这个功能,可以设置为 exportselection=0
selectbackground选中文字时的背景颜色
selectforeground选中文字时的前景色
show指定文本框内容以何种样式的字符显示,比如密码可以将值设为 show="*"
textvariable输入框内值,也称动态字符串,使用 StringVar() 对象来设置,而 text 为静态字符串对象
xscrollcommand设置输入框内容滚动条,当输入的内容大于输入框的宽度时使用户

常用方法:

方法说明
delete()根据索引值删除输入框内的值
get()获取输入框内的值
set()设置输入框内的值
insert()在指定的位置插入字符串
index()返回指定的索引值
select_clear()取消选中状态
select_adujst()确保输入框中选中的范围包含 index 参数所指定的字符,选中指定索引和光标所在位置之前的字符
select_from (index)设置一个新的选中范围,通过索引值 index 来设置
select_present()返回输入框是否有处于选中状态的文本,如果有则返回 true,否则返回 false。
select_to()选中指定索引与光标之间的所有值
select_range()选中指定索引与光标之间的所有值,参数值为 start,end,要求 start 必须小于 end。

基本案例:

# 创建一个文本框
tx = Entry(window, width=20)
tx.place(x=100, y=10)

按钮

Button 控件是 Tkinter 中常用的窗口部件之一,同时也是实现程序与用户交互的主要控件。通过用户点击按钮的行为来执行回调函数,是 Button 控件的主要功用。首先自定义一个函数或者方法,然后将函数与按钮关联起来,最后,当用户按下这个按钮时,Tkinter 就会自动调用相关函数。

基本属性:

属性说明
anchor控制文本所在的位置,默认为中心位置(CENTER)
activebackground当鼠标放在按钮上时候,按妞的背景颜色
activeforeground当鼠标放在按钮上时候,按钮的前景色
bd按钮边框的大小,默认为 2 个像素
bg按钮的背景色
command用来执行按钮关联的回调函数。当按钮被点击时,执行该函数
fg按钮的前景色
font按钮文本的字体样样式
height按钮的高度
highlightcolor按钮控件高亮处要显示的颜色
image按钮上要显示的图片
justify按钮显示多行文本时,用来指定文本的对齐方式,参数值有 LEFT/RIGHT/CENTER
padx/padypadx 指定 x 轴(水平方向)的间距大小,pady 则表示 y轴(垂直方向)的间距大小
ipadx/ipadyipadx 指标签文字与标签容器之间的横向距离;ipady 则表示标签文字与标签容器之间的纵向距离
state设置按钮的可用状态,可选参数有NORMAL/ACTIVE/DISABLED,默认为 NORMAL
text按钮控件要显示的文本

基本案例:

# 导入tkinter模块
from tkinter import *
# 导入tkinter模型中的messagebox
from tkinter import messagebox
​
# 给按钮绑定点击事件
def do_click():
    # 触发按钮点击事件之后,获取文本框输入的值
    text = tx.get()
    print(f"被点击了,text={text}")
    messagebox.showinfo("提示", text)
​
# 创建一个按钮
btn_search = Button(window, text="点我试试", width=6, command=do_click)
btn_search.place(x=260, y=5)

更多组件的基本使用请见此处资料。

Treeview组件

ttk.Treeview 控件可将多项内容分层级显示。每个数据项抖带有一个文本标签、一张图片(可选)和一个数据列表(可选)。这些数据值将在树标签后面分列显示。

  • 基本属性:

属性描述
columns列标识的列表,定义了列的数量和名称。
displaycolumns列标识的列表(索引可为符号或整数),指定要显示的数据列及显示顺序,或为字符串 “#all”。
height指定可见的行数。注意:所需宽度由各列宽度之和决定。
padding指定控件内部的留白。为不超过四个元素的长度列表。
selectmode控制内部类如何进行选中项的管理。可为 extended、browse 或 none。若设为 extended(默认),则可选中多个项。若为 browse ,则每次只能选中一项。若为 none,则无法修改选中项。请注意,代码和 tag 绑定可自由进行选中操作,不受本属性的限制。
show由0个或下列值组成的列表,指定要显示树的哪些元素。tree :在 #0 列显示树的文本标签。headings :显示标题行。默认为“tree headings”,显示所有元素。 注意 :第 #0 列一定是指 tree 列,即便未设置 show="tree" 也一样。

基本案例:

# 导入Treeview组件
from tkinter.ttk import Treeview
# 创建TreeView组件
# show="headings" 用于隐藏首列
tv = Treeview(window,
              columns=("id", "bookname", "price", "booktype"),
              show="headings")
# 设置Treeview显示位置
tv.place(x=10, y=40)

  • 常用方法:

方法描述
bbox(item, column=None)返回指定item的框选范围,或者单元格的框选范围
column( cid, option=None, **kw)设置或者查询某一列的属性
delete(*items)删除指定行或者节点(含子节点)
vdetach(*items)与delete类似,不过不是真正删除,而是隐藏了相关内容。可以用move方法重新显示v
exists(item)判断指定的item是否存在
focus(item=None)获得选定item的iid,或者选中指定item。
get_children(item=None)返回指定item的子节点
heading(column, option=None, **kw)设置或者查询表头行的配置参数
identify(component, x, y)返回在坐标(x,y)处的部件信息。部件包括:region(heading,cell等), item, column, row, 和 element。
identify_element(x, y)返回在(x,y)处的元素。
identify_region(x, y)返回坐标(x,y)处的Tree view组成部分
identify_row(y)给定y坐标,返回指定item索引
index(item)返回数字化的item索引,从0开始
set_children(item, *newchildren)设置item的新子节点为newchildren,现有的子节点会被移除。一般用于树形结构中。
insert(parent, index, iid=None, **kw)插入一个新的item
item(item, option=None, **kw)返回item节点的相关信息
move(item, parent, index)move()方法有两种作用: (1)将detach的item重新显示(reattach) (2)移动item指定的节点到parent的子节点中,位置由index指定
next(item)返回item的下一个节点
parent(item)返回item的父节点
prev(item)返回item的前一个节点
see(item)保证item指定的节点在Treeview控件中可见
selection(items=None)返回当前选定的节点的iid
selection_set(*items)选中items指定的节点
selection_remove(*items)从当前选择中移除items指定的节点
selection_add(*items)将items指定的节点添加到当前的选择中
selection_toggle(*items)选中的节点变为不选中,未选中的节点变为选中
set(item, column=None, value=None)设置或者获得节点信息
tag_bind( tagname, sequence=None, callback=None)给tagname指定的tag绑定事件以及回调函数
tag_configure( tagname, option=None, **kw)配置或者获得tag的有关信息
tag_has(tagname, item=None)判断tag是否存在或者是tag与那些节点关联

  • column列选项

column( cid, option=None, **kw)查询或者修改指定列的配置。cid可以是整数,也可以列的别名。如果不输入option,则返回目前的配置选项字典。Treeview列的选项有:

选项含义
anchor对齐模式。取值有n,e,s,w,ne,nw,se,sw和center。
id列的名称或者标识
minwidth列的最小宽度,调整列宽的时候,不会小于这个数值。默认值是20
stretch是否随着窗口大小的调整而拉伸Treeview。默认值是True
width定义列宽。默认值是200

基础案例:

# 设置列的宽度及对齐方式
# tv.column("#0",width=10)
tv.column("id", width=90, anchor=CENTER)
tv.column("bookname", width=200, anchor=CENTER)
tv.column("price", width=96, anchor=CENTER)
tv.column("booktype", width=90, anchor=CENTER)

  • heading表头行:

heading(column, option=None, **kw)设置或者查询表头行的配置参数。如果是表格形式的,column是列的位置(就是第几列,从0计数)或者列的别名。如果是树形结构的(比如文件目录),column的值为'#0'。 如果没有option参数,返回的是当前的配置数据。 heading的选项有:

选项含义
anchor对齐模式。取值有n,e,s,w,ne,nw,se,sw和center。
command与指定列相关的回调函数
image在表头显示图片
text在表头显示文本
state当前列的状态

基本案例:

# 设置列的表头
# tv.heading("#0",text="")
tv.heading("id", text="书本编号")
tv.heading("bookname", text="书本名称")
tv.heading("price", text="书本价格")
tv.heading("booktype", text="书本类型")

  • insert新增数据行:

insert(parent, index, iid=None, **kw)插入一个新的item。 (1)parent 对于表格类型的Treeview,parent一般为空。对于树形类型的Treeview,parent为父节点。 (2)index 指明在何处插入新的item。可以是'end',也可以是数字。比如,如果要让新插入的item成为第一个子节点或者在第一行,index就设为0。如果是第二个子节点或者第二行,就是设置index=1。如果在最末端插入item,就设置index='end' (3)iid 如果没有赋值,就使用系统自动生成的id。如果输入了id,必须保证与现有的id不重复。否则系统会自动生成id。 (4)**kw 设置插入item的属性。支持的属性有:

选项含义
image显示图像
open针对树形结构,确认插入的item是打开还是折叠状态。True打开,False为折叠。
tags为新插入的item设置tag标签
text显示文字
values在表格结构中,要显示的数值。这些数值是按照逻辑结构赋值的,也就是按照columns设定的列次序来赋值。如果输入的个数少于columns指定列数,则插入空白字符串

基本案例:

# 数据绑定
tv.insert('', END, values=(1, "山海经", 100, '玄幻'))
tv.insert('', END, values=(2, "金刚经", 110, '经书'))
tv.insert('', END, values=(3, "三字经", 120, '内功心法'))
tv.insert('', END, values=(4, "道德经", 100, '内功心法'))

另一种

import tkinter as tk  # 导入 tkinter 库,用于创建 GUI 程序
import tkinter.ttk as ttk  # 导入 tkinter.ttk 模块,用于创建包含主题小部件的 GUI 程序

# 创建根窗口
root = tk.Tk()
root.title("简单示例")

# 设置窗口大小
root.geometry('400x400')

# 创建一个Treeview
tree = ttk.Treeview(root, show='tree')
tree.pack()

# 添加一级树节点
treeF1 = tree.insert("", 0, '北京', text='中国北京', values=('F1'))
treeF2 = tree.insert("", 1, '河北', text='中国河北', values=('F2'))
treeF3 = tree.insert("", 2, '广州', text='中国广州', values=('F3'))

# 添加二级树节点
treeF1_1 = tree.insert(treeF1, 0, '东城区', text='北京东城区', values=('F1_1'))
treeF1_2 = tree.insert(treeF1, 1, '西城区', text='北京西城区', values=('F1_2'))

treeF2_1 = tree.insert(treeF2, 0, '石家庄', text='河北石家庄', values=('F2_1'))
treeF2_2 = tree.insert(treeF2, 1, '邯郸', text='河北邯郸', values=('F2_2'))

# 添加三级树节点
treeF2_2_1 = tree.insert(treeF2_2, 0, '永年区', text='河北石家庄永年区', values=('F2_2_1'))
treeF2_2_2 = tree.insert(treeF2_2, 1, '丹山区', text='河北邯郸丹山区', values=('F2_2_2'))

# 开始运行主事件循环
tk.mainloop()

封装后的DBHelper

DBHelper只是对基本操作进行了简单封装处理:

from pymysql import *  # 导入 pymysql 库中的所有内容,包括 Connection、Cursor 等
from pymysql.cursors import Cursor  # 从 pymysql.cursors 模块中导入 Cursor 类

class DBHelper:
    conn: Connection = None  # 初始化 Connection 对象为 None,用于存储数据库连接
    curs: Cursor = None  # 初始化 Cursor 对象为 None,用于执行 SQL 查询和操作数据库

    def __init__(self):
        # 在初始化方法中建立数据库连接
        self.conn = Connection(user="root", password="1234",
                               port=3306, host="localhost",
                               database="vue", charset="utf8",
                               autocommit=True)
        self.curs = self.conn.cursor()  # 初始化 Cursor 对象

    def close(self):
        self.curs.close()  # 关闭 Cursor 对象
        self.conn.close()  # 关闭数据库连接

    def execute(self, sql: str, params: tuple):
        try:
            self.curs.execute(sql, params)  # 执行 SQL 操作
        except Exception as ex:
            print(f"操作失败,提示:{ex}")  # 操作失败时打印异常信息
        finally:
            self.close()  # 最终关闭数据库连接

    def find(self, sql: str, params: tuple):
        try:
            self.curs.execute(sql, params)  # 执行 SQL 查询
            return self.curs.fetchall()  # 返回查询结果
        except Exception as ex:
            print(f"查询失败,提示:{ex}")  # 查询失败时打印异常信息
        finally:
            self.close()  # 最终关闭数据库连接
        return None  # 如果查询失败,返回 None

dao层定义

from utils.DBHelper import *  # 导入 DBHelper 类,用于操作数据库

class BookDao:
    db = None  # 初始化 DBHelper 对象为 None

    def __init__(self):
        self.db = DBHelper()  # 初始化 DBHelper 对象,用于数据库操作

    def add(self, book: tuple = None):
        sql = """insert into t_book_vue(bookname,price,booktype) values(%s,%s,%s)"""  # 插入图书信息的 SQL 语句
        self.db.execute(sql, book)  # 执行插入操作

    def query(self, book: tuple = None):
        sql = "select * from t_book_vue where bookname like %s"  # 查询图书信息的 SQL 语句
        return self.db.find(sql, book)  # 执行查询操作并返回结果

    def delete(self, bid: int = 0):
        sql = """delete from t_book_vue where id=%s"""  # 删除图书信息的 SQL 语句
        self.db.execute(sql, (bid,))  # 执行删除操作

if __name__ == '__main__':
    bd = BookDao()  # 创建 BookDao 实例
    # bd.add(("222",123,"22"))  # 调用 add 方法插入图书信息
    # print(bd.query(('%%',)))  # 调用 query 方法查询图书信息
    # bd.delete(56)  # 调用 delete 方法删除指定图书信息

综合案例

  • 查询功能实现:

def do_click():
    # 触发按钮点击事件之后,获取文本框输入的值
    bookname = tx.get()
    # print(f"被点击了,bookname={bookname}")
    # messagebox.showinfo("提示", bookname)
    book = BookDao()
    res = book.query(("%"+bookname+"%",))
    # 清空表格数据
    for i in tv.get_children():
        tv.delete(i)
    # 绑定动态数据
    for b in res:
        tv.insert('',END,values=b)
  • 删除功能实现:

def do_delete():
    # 如何获取当前Treeview选中行索引
    index = tv.selection()
    # 判断是否选中行
    assert len(index) > 0
    print(index)
    # 根据行索引获取数据行
    print(tv.item(index))
    # 删除选中行
    # tv.delete(index)
    book = BookDao()
    book.delete(tv.item(index)["values"][0])
    # 调用刷新方法
    do_click()
  • 新增功能实现:

from tkinter.simpledialog import *
​
def do_add():
    bookname = askstring('提示', '请输入书本名称')
    price = askfloat('提示', '请输入书本价格')
    booktype = askstring('提示', '请输入书本类型')
    print(f"bookname={bookname},price={price},booktype={booktype}")
    # tv.insert('', END, values=(1,bookname, price, booktype))
    book = BookDao()
    book.add((bookname,price,booktype))
    # 调用刷新方法
    do_click()
  • 28
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值