Python中Tkinter GUI编程详细教程

 更新时间:2025年12月13日 10:30:02   作者:一个平凡而乐于分享的小比特  
Tkinter作为Python编程语言中构建GUI的一个重要组件,其教程对于任何希望将Python应用到实际编程中的开发者来说都是宝贵的资源,这篇文章主要介绍了Python中Tkinter GUI编程的相关资料,需要的朋友可以参考下

前言

Tkinter 是 Python 的标准 GUI 库,可以快速创建图形用户界面。本教程将带你从基础开始学习 Tkinter。

1. Tkinter 简介

Tkinter 是 Python 自带的 GUI 工具包,基于 Tk GUI 工具集。它的优点包括:

  • 跨平台(Windows、macOS、Linux)
  • 简单易学
  • 无需额外安装

2. 第一个 Tkinter 程序

import tkinter as tk

# 创建主窗口
root = tk.Tk()
root.title("我的第一个 Tkinter 程序")
root.geometry("300x200")  # 设置窗口大小

# 创建标签
label = tk.Label(root, text="Hello, Tkinter!")
label.pack()  # 将标签添加到窗口

# 创建按钮
def on_click():
    label.config(text="按钮被点击了!")

button = tk.Button(root, text="点击我", command=on_click)
button.pack()

# 启动主循环
root.mainloop()

3. 窗口和基础组件

3.1 创建窗口

import tkinter as tk

root = tk.Tk()
root.title("窗口标题")
root.geometry("400x300")  # 宽度x高度
root.resizable(True, False)  # 宽度可调整,高度不可调整
root.iconbitmap("icon.ico")  # 设置窗口图标(仅Windows)
root.configure(bg="lightblue")  # 设置背景颜色

3.2 常用组件

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()
root.title("基础组件演示")
root.geometry("400x400")

# 1. 标签
label = tk.Label(root, text="这是一个标签", font=("Arial", 12), fg="blue")
label.pack(pady=10)

# 2. 按钮
def button_click():
    messagebox.showinfo("提示", "按钮被点击了!")

button = tk.Button(root, text="点击我", command=button_click, bg="lightgreen")
button.pack(pady=10)

# 3. 输入框
entry = tk.Entry(root, width=30)
entry.insert(0, "默认文本")  # 设置默认文本
entry.pack(pady=10)

# 4. 文本框
text = tk.Text(root, height=5, width=30)
text.insert("1.0", "这是一个多行文本框\n可以输入多行文本")
text.pack(pady=10)

# 5. 复选框
check_var = tk.IntVar()
checkbutton = tk.Checkbutton(root, text="选择我", variable=check_var)
checkbutton.pack(pady=10)

# 6. 单选框
radio_var = tk.StringVar(value="选项1")
radio1 = tk.Radiobutton(root, text="选项1", variable=radio_var, value="选项1")
radio2 = tk.Radiobutton(root, text="选项2", variable=radio_var, value="选项2")
radio1.pack()
radio2.pack()

root.mainloop()

4. 布局管理

Tkinter 有三种布局管理器:pack、grid 和 place。

4.1 pack 布局

import tkinter as tk

root = tk.Tk()
root.title("pack 布局")
root.geometry("300x200")

# pack 按照添加顺序排列组件
tk.Label(root, text="标签1", bg="red").pack(fill=tk.X, padx=10, pady=5)
tk.Label(root, text="标签2", bg="green").pack(fill=tk.X, padx=10, pady=5)
tk.Label(root, text="标签3", bg="blue").pack(fill=tk.X, padx=10, pady=5)

# side 参数控制方向
tk.Button(root, text="左").pack(side=tk.LEFT, padx=5)
tk.Button(root, text="右").pack(side=tk.RIGHT, padx=5)
tk.Button(root, text="顶部").pack(side=tk.TOP, pady=5)
tk.Button(root, text="底部").pack(side=tk.BOTTOM, pady=5)

root.mainloop()

4.2 grid 布局(最常用)

import tkinter as tk

root = tk.Tk()
root.title("grid 布局")
root.geometry("300x200")

# 使用 grid 布局,类似表格
tk.Label(root, text="用户名:").grid(row=0, column=0, padx=10, pady=10, sticky=tk.W)
tk.Entry(root).grid(row=0, column=1, padx=10, pady=10)

tk.Label(root, text="密码:").grid(row=1, column=0, padx=10, pady=10, sticky=tk.W)
tk.Entry(root, show="*").grid(row=1, column=1, padx=10, pady=10)

# 跨列显示按钮
tk.Button(root, text="登录").grid(row=2, column=0, columnspan=2, pady=20, sticky=tk.EW)

# 配置列权重,使第二列可以伸缩
root.grid_columnconfigure(1, weight=1)

root.mainloop()

4.3 place 布局(精确位置)

import tkinter as tk

root = tk.Tk()
root.title("place 布局")
root.geometry("300x200")

# 使用绝对坐标放置组件
tk.Label(root, text="绝对定位", bg="yellow").place(x=50, y=50)

# 使用相对位置
tk.Label(root, text="相对定位", bg="lightblue").place(relx=0.5, rely=0.5, anchor=tk.CENTER)

root.mainloop()

5. 事件处理

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()
root.title("事件处理")
root.geometry("400x300")

# 1. 按钮点击事件
def button_click():
    messagebox.showinfo("事件", "按钮被点击")

button = tk.Button(root, text="点击事件", command=button_click)
button.pack(pady=10)

# 2. 键盘事件
def on_key_press(event):
    print(f"按下了键: {event.char}")
    label.config(text=f"按下了: {event.char}")

label = tk.Label(root, text="按任意键")
label.pack(pady=10)

root.bind("<Key>", on_key_press)

# 3. 鼠标事件
def on_click(event):
    print(f"鼠标点击位置: ({event.x}, {event.y})")

canvas = tk.Canvas(root, width=200, height=100, bg="lightgray")
canvas.pack(pady=10)
canvas.bind("<Button-1>", on_click)  # 左键点击

# 4. 输入框事件
def on_entry_change(event):
    print(f"输入框内容: {entry.get()}")

entry = tk.Entry(root, width=30)
entry.pack(pady=10)
entry.bind("<KeyRelease>", on_entry_change)  # 键盘释放时触发

root.mainloop()

6. 高级组件

import tkinter as tk
from tkinter import ttk, messagebox, filedialog

root = tk.Tk()
root.title("高级组件")
root.geometry("500x400")

# 1. 下拉菜单
def on_menu_select(event):
    messagebox.showinfo("选择", f"选择了: {combo.get()}")

combo = ttk.Combobox(root, values=["选项1", "选项2", "选项3"])
combo.set("请选择")
combo.pack(pady=10)
combo.bind("<<ComboboxSelected>>", on_menu_select)

# 2. 列表框
listbox = tk.Listbox(root, height=4)
for item in ["项目1", "项目2", "项目3", "项目4", "项目5"]:
    listbox.insert(tk.END, item)
listbox.pack(pady=10)

def show_selected():
    selected = listbox.curselection()
    if selected:
        messagebox.showinfo("选择", f"选择了: {listbox.get(selected[0])}")

tk.Button(root, text="显示选中项", command=show_selected).pack(pady=5)

# 3. 滚动条
frame = tk.Frame(root)
frame.pack(pady=10)

text = tk.Text(frame, height=5, width=40)
scrollbar = tk.Scrollbar(frame, command=text.yview)
text.configure(yscrollcommand=scrollbar.set)

text.pack(side=tk.LEFT)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

# 4. 进度条
progress = ttk.Progressbar(root, length=200, mode='indeterminate')
progress.pack(pady=10)

def start_progress():
    progress.start(10)

def stop_progress():
    progress.stop()

tk.Button(root, text="开始进度", command=start_progress).pack(pady=5)
tk.Button(root, text="停止进度", command=stop_progress).pack(pady=5)

# 5. 文件对话框
def open_file():
    filepath = filedialog.askopenfilename(
        title="选择文件",
        filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
    )
    if filepath:
        messagebox.showinfo("文件", f"选择了: {filepath}")

tk.Button(root, text="打开文件", command=open_file).pack(pady=10)

root.mainloop()

7. 综合示例

创建一个简单的待办事项应用:

import tkinter as tk
from tkinter import ttk, messagebox
from datetime import datetime

class TodoApp:
    def __init__(self, root):
        self.root = root
        self.root.title("待办事项管理")
        self.root.geometry("500x400")
        
        self.tasks = []
        self.setup_ui()
    
    def setup_ui(self):
        # 创建框架
        input_frame = tk.Frame(self.root)
        input_frame.pack(pady=10, padx=10, fill=tk.X)
        
        # 输入框和添加按钮
        tk.Label(input_frame, text="新任务:").pack(side=tk.LEFT, padx=(0, 10))
        
        self.task_entry = tk.Entry(input_frame, width=30)
        self.task_entry.pack(side=tk.LEFT, padx=(0, 10))
        self.task_entry.bind("<Return>", lambda e: self.add_task())
        
        tk.Button(input_frame, text="添加", command=self.add_task, bg="lightgreen").pack(side=tk.LEFT)
        
        # 任务列表
        list_frame = tk.Frame(self.root)
        list_frame.pack(pady=10, padx=10, fill=tk.BOTH, expand=True)
        
        # 创建树形视图显示任务
        columns = ("序号", "任务", "创建时间", "状态")
        self.tree = ttk.Treeview(list_frame, columns=columns, show="headings", height=10)
        
        for col in columns:
            self.tree.heading(col, text=col)
            self.tree.column(col, width=100)
        
        self.tree.column("任务", width=200)
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        
        self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 操作按钮
        button_frame = tk.Frame(self.root)
        button_frame.pack(pady=10)
        
        tk.Button(button_frame, text="标记完成", command=self.complete_task, bg="lightblue").pack(side=tk.LEFT, padx=5)
        tk.Button(button_frame, text="删除任务", command=self.delete_task, bg="lightcoral").pack(side=tk.LEFT, padx=5)
        tk.Button(button_frame, text="清空全部", command=self.clear_all, bg="orange").pack(side=tk.LEFT, padx=5)
        
        # 状态标签
        self.status_label = tk.Label(self.root, text="总任务数: 0", relief=tk.SUNKEN, anchor=tk.W)
        self.status_label.pack(side=tk.BOTTOM, fill=tk.X)
    
    def add_task(self):
        task_text = self.task_entry.get().strip()
        if task_text:
            task_id = len(self.tasks) + 1
            create_time = datetime.now().strftime("%H:%M:%S")
            self.tasks.append({
                "id": task_id,
                "text": task_text,
                "time": create_time,
                "status": "待完成"
            })
            
            self.tree.insert("", tk.END, values=(task_id, task_text, create_time, "待完成"))
            self.task_entry.delete(0, tk.END)
            self.update_status()
        else:
            messagebox.showwarning("警告", "请输入任务内容")
    
    def complete_task(self):
        selected = self.tree.selection()
        if selected:
            item = self.tree.item(selected[0])
            task_id = item['values'][0]
            
            for task in self.tasks:
                if task["id"] == task_id:
                    task["status"] = "已完成"
                    break
            
            self.tree.item(selected[0], values=(item['values'][0], item['values'][1], item['values'][2], "已完成"))
            self.update_status()
        else:
            messagebox.showwarning("警告", "请选择要完成的任务")
    
    def delete_task(self):
        selected = self.tree.selection()
        if selected:
            if messagebox.askyesno("确认", "确定要删除选中的任务吗?"):
                item = self.tree.item(selected[0])
                task_id = item['values'][0]
                
                self.tasks = [task for task in self.tasks if task["id"] != task_id]
                self.tree.delete(selected[0])
                self.update_status()
        else:
            messagebox.showwarning("警告", "请选择要删除的任务")
    
    def clear_all(self):
        if self.tasks and messagebox.askyesno("确认", "确定要清空所有任务吗?"):
            self.tasks.clear()
            for item in self.tree.get_children():
                self.tree.delete(item)
            self.update_status()
    
    def update_status(self):
        total = len(self.tasks)
        completed = sum(1 for task in self.tasks if task["status"] == "已完成")
        self.status_label.config(text=f"总任务数: {total} | 已完成: {completed} | 待完成: {total - completed}")

def main():
    root = tk.Tk()
    app = TodoApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()

总结

这个教程涵盖了 Tkinter 的基础知识和常用功能:

  1. 基础组件:Label、Button、Entry、Text 等
  2. 布局管理:pack、grid、place 三种布局方式
  3. 事件处理:鼠标、键盘和各种组件事件
  4. 高级组件:Combobox、Listbox、Progressbar 等
  5. 综合应用:创建完整的 GUI 应用程序

通过这个教程,你应该能够开始使用 Tkinter 创建自己的图形界面应用程序。继续练习的最好方式是尝试修改示例代码,添加新功能,或者创建自己的小项目。

到此这篇关于Python中Tkinter GUI编程详细教程的文章就介绍到这了,更多相关Tkinter GUI编程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何基于pythonnet调用halcon脚本

    如何基于pythonnet调用halcon脚本

    这篇文章主要介绍了如何基于pythonnet调用halcon脚本,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • python实现证件照换底功能

    python实现证件照换底功能

    这篇文章主要为大家详细介绍了python实现证件照换底功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • 初探利用Python进行图文识别(OCR)

    初探利用Python进行图文识别(OCR)

    这篇文章主要介绍了初探利用Python进行图文识别(OCR),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • 利用Pygame制作简单动画的示例详解

    利用Pygame制作简单动画的示例详解

    Pygame是被设计用来写游戏的python模块集合,Pygame是在优秀的SDL库之上开发的功能性包。本文将利用Pygame制作简易的动画,感兴趣的可以学习一下
    2022-05-05
  • Python常见格式化字符串方法小结【百分号与format方法】

    Python常见格式化字符串方法小结【百分号与format方法】

    这篇文章主要介绍了Python常见格式化字符串方法,结合实例形式分析了百分号方法和format函数进行字符串格式化的具体使用技巧,需要的朋友可以参考下
    2016-09-09
  • Python 使用生成器代替线程的方法

    Python 使用生成器代替线程的方法

    这篇文章主要介绍了Python 使用生成器代替线程的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-08-08
  • Python合并字符串的3种方法

    Python合并字符串的3种方法

    这篇文章主要介绍了Python合并字符串的3种方法,本文讲解了使用+=操作符、使用%操作符、使用String的' '.join()方法3种方法,需要的朋友可以参考下
    2015-05-05
  • Python实现异常值自动检测的案例分享

    Python实现异常值自动检测的案例分享

    在数据分析和机器学习中,异常值的检测是一个关键步骤,它有助于识别数据中的异常模式和离群点,本文将介绍Python中异常值检测的实战案例,使用一些常见的技术和库,为大家提供全面的示例代码和详细解释
    2024-01-01
  • Python 正则表达式实现计算器功能

    Python 正则表达式实现计算器功能

    本篇文章主要介绍了Python 正则表达式实现计算器功能的示例。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04
  • python创建文件备份的脚本

    python创建文件备份的脚本

    这篇文章主要介绍了python创建文件备份的脚本,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09

最新评论