Tkinter界面开发


PyQt5新手教程(五万字)


一、Tkinter 简介

Tkinter 是 Python 标准库中的一个模块,用于创建图形用户界面 (GUI)。 它是最早的也是最常用的 GUI 工具包之一,因其易用性和直接与 Python 绑定而广受欢迎。

  • 基于Tcl/Tk(Tk 是 Tcl 语言开发的跨平台 GUI 工具包)。Tkinter 提供了与 Tk 的接口,使得 Python 程序员能够创建 GUI 应用程序。
  • 跨平台支持:支持在Windows、macOS和Linux上运行,且发行版一致。
    • tkinter是Python的标准库之一,通常已经预安装在大多数的Python发行版中。
    • 如果你的环境中没有安装tkinter,使用以下命令来安装:pip install tkinter

二、Tkinter 与 PyQt 的蒙娜丽莎

tkinter 和 PyQt 是两种常用的 Python GUI 库,它们各有优缺点,适合不同的应用场景。以下是这两个库的比较,以及它们的特点和使用场景。

Tkinter PyQt
安装 内置于 Python 需要额外安装
学习曲线 较平缓(易于学习,快速上手) 较陡
功能 功能有限且组件较少 功能强大且组件丰富
界面风格 较传统 现代且可定制
跨平台支持 Windows、macOS、Linux Windows、macOS、Linux
使用领域 初学者、简易程序 企业级、复杂程序

三、Tkinter 布局管理器

3.1、简介

  • 根窗口(Root Window):是所有Tkinter应用程序的主窗口,通常由Tk()类实例化。它是其他所有窗口部件的父窗口。
  • 组件(Widgets):是指应用程序中的各种界面元素,是用户与应用程序交互的主要方式。
    • 标签(Label):用于显示文本或图像的静态控件。标签常用于显示提示信息或标题。
    • 按钮(Button):用户可以点击按钮来触发某些动作。可以为按钮设置文本或图像,并指定点击时调用的回调函数。
    • 文本框(Entry):单行文本输入控件,用户可以在其中输入和编辑文本。
    • 文本控件(Text):多行文本输入控件,允许用户输入和编辑多行文本。它支持丰富的文本样式和颜色。
    • 列表框(Listbox):显示列表项的控件,用户可以从中选择一个或多个项目。
    • 复选框(Checkbutton):允许用户选择或取消选择的按钮。常用于表示布尔选项。
    • 单选按钮(Radiobutton):一组选项中只能选择一个的按钮。常用于从多个互斥的选项中选择一个。
    • 框架(Frame):用于组织其他部件的容器。框架可以嵌套,用于创建复杂的布局。
    • 画布(Canvas):强大的绘图区域,用于绘制图形、图像和其他复杂的自定义界面元素。
  • 布局管理器(Geometry Managers):负责组织和排列部件在窗口中的位置。Tkinter提供了几种布局管理器,每种管理器有不同的布局方式。
    • 顺序-布局管理器 pack按照添加顺序将部件放置在窗口中。可以通过side参数指定部件排列的方向(如top、bottom、left、right)。
    • 网格-布局管理器 grid使用行和列来精确定位部件。可以通过row和column参数指定部件的位置。
    • 坐标-布局管理器 place使用x和y坐标来精确定位部件
  • 主循环 root.mainloop():(1)启动Tkinter的主事件循环,使应用程序保持运行并处理所有用户交互(如:鼠标点击、键盘输入等)和窗口更新。(2)没有它,窗口不会响应用户输入或显示任何内容。(3)当用户关闭窗口时,自动结束事件处理循环并关闭程序,而不需要显示调用 root.destroy()。
  • 手动摧毁窗口 root.destroy():用于完全销毁 tkinter 主窗口。它不仅关闭窗口并终止应用程序的运行,包括停止所有与窗口相关的事件处理循环,并清理相关的资源(如:内存或文件句柄)。

3.2、项目实战

3.2.1、布局管理器:pack

在这里插入图片描述

import tkinter as tk
from tkinter import messagebox

def submit():
    name = name_entry.get()
    gender = gender_var.get()
    subscribed = subscribe_var.get()

    gender_text = "Male" if gender == 1 else "Female"
    subscribed_text = "Yes" if subscribed == 1 else "No"

    messagebox.showinfo("Information", f"Name: {
      
      name}\nGender: {
      
      gender_text}\nSubscribed: {
      
      subscribed_text}")

if __name__ == '__main__':
	root = tk.Tk()  # 创建主窗口
	root.title("Simple Form with pack()")  # 设置主窗口标题
	
    # 创建部件并使用 pack 布局管理器
	tk.Label(root, text="Name:").pack(anchor='w', padx=10, pady=5)
	name_entry = tk.Entry(root)
	name_entry.pack(padx=10, pady=5)
	
	tk.Label(root, text="Gender:").pack(anchor='w', padx=10, pady=5)
	gender_var = tk.IntVar()
	tk.Radiobutton(root, text="Male", variable=gender_var, value=1).pack(anchor='w', padx=10, pady=2)
	tk.Radiobutton(root, text="Female", variable=gender_var, value=2).pack(anchor='w', padx=10, pady=2)
	
	subscribe_var = tk.IntVar()
	tk.Checkbutton(root, text="Subscribe to newsletter", variable=subscribe_var).pack(anchor='w', padx=10, pady=5)
	
	submit_button = tk.Button(root, text="Submit", command=submit)
	submit_button.pack(pady=10)
	
	root.mainloop()  # 进入主循环

3.2.2、布局管理器:grid

在这里插入图片描述

import tkinter as tk
from tkinter import messagebox


def submit():
    name = name_entry.get()
    gender = gender_var.get()
    subscribed = subscribe_var.get()

    gender_text = "Male" if gender == 1 else "Female"
    subscribed_text = "Yes" if subscribed == 1 else "No"

    messagebox.showinfo("Information", f"Name: {
      
      name}\nGender: {
      
      gender_text}\nSubscribed: {
      
      subscribed_text}")

if __name__ == '__main__':
    root = tk.Tk()  # 创建主窗口
    root.title("Simple Form")  # 设置主窗口标题
    
    # 创建部件并使用 grid 布局管理器
    tk.Label(root, text="Name:").grid(row=0, column=0, padx=10, pady=5, sticky=tk.W)
    name_entry = tk.Entry(root)
    name_entry.grid(row=0, column=1, padx=10, pady=5)
    
    tk.Label(root, text="Gender:").grid(row=1, column=0, padx=10, pady=5, sticky=tk.W)
    gender_var = tk.IntVar()
    tk.Radiobutton(root, text="Male", variable=gender_var, value=1).grid(row=1, column=1, padx=10, pady=5, sticky=tk.W)
    tk.Radiobutton(root, text="Female", variable=gender_var, value=2).grid(row=1, column=2, padx=10, pady=5, sticky=tk.W)
    
    subscribe_var = tk.IntVar()
    tk.Checkbutton(root, text="Subscribe to newsletter", variable=subscribe_var).grid(row=2, columnspan=3, padx=10, pady=5)
    
    submit_button = tk.Button(root, text="Submit", command=submit)
    submit_button.grid(row=3, columnspan=3, pady=10)

    root.mainloop()  # 进入主循环

3.2.3、布局管理器:place

在这里插入图片描述

import tkinter as tk
from tkinter import messagebox

def submit():
    name = name_entry.get()
    gender = gender_var.get()
    subscribed = subscribe_var.get()

    gender_text = "Male" if gender == 1 else "Female"
    subscribed_text = "Yes" if subscribed == 1 else "No"

    messagebox.showinfo("Information", f"Name: {
      
      name}\nGender: {
      
      gender_text}\nSubscribed: {
      
      subscribed_text}")

if __name__ == '__main__':
    root = tk.Tk()  # 创建主窗口
    root.title("Simple Form with place()")  # 设置主窗口标题

    # 创建部件并使用 place 布局管理器
    tk.Label(root, text="Name:").place(x=20, y=20, anchor=tk.W)
    name_entry = tk.Entry(root)
    name_entry.place(x=80, y=20, width=200)

    tk.Label(root, text="Gender:").place(x=20, y=60, anchor=tk.W)
    gender_var = tk.IntVar()
    tk.Radiobutton(root, text="Male", variable=gender_var, value=1).place(x=80, y=60, anchor=tk.W)
    tk.Radiobutton(root, text="Female", variable=gender_var, value=2).place(x=140, y=60, anchor=tk.W)

    subscribe_var = tk.IntVar()
    tk.Checkbutton(root, text="Subscribe to newsletter", variable=subscribe_var).place(x=20, y=100, anchor=tk.W)

    submit_button = tk.Button(root, text="Submit", command=submit)
    submit_button.place(x=20, y=140)

    root.geometry("300x200")  # 设置窗口大小
    root.mainloop()  # 进入主循环

四、Tkinter 常用组件

4.1、简介

  • 组件(Widgets):是指应用程序中的各种界面元素,是用户与应用程序交互的主要方式。
    • 标签(Label):用于显示文本或图像的静态控件。标签常用于显示提示信息或标题。
    • 按钮(Button):用户可以点击按钮来触发某些动作。可以为按钮设置文本或图像,并指定点击时调用的回调函数。
    • 文本框(Entry):单行文本输入控件,用户可以在其中输入和编辑文本。
    • 文本控件(Text):多行文本输入控件,允许用户输入和编辑多行文本。它支持丰富的文本样式和颜色。
    • 列表框(Listbox):显示列表项的控件,用户可以从中选择一个或多个项目。
    • 复选框(Checkbutton):允许用户选择或取消选择的按钮。常用于表示布尔选项。
    • 单选按钮(Radiobutton):一组选项中只能选择一个的按钮。常用于从多个互斥的选项中选择一个。
    • 框架(Frame):用于组织其他部件的容器。框架可以嵌套,用于创建复杂的布局。
    • 画布(Canvas):强大的绘图区域,用于绘制图形、图像和其他复杂的自定义界面元素。

4.2、root.mainloop() + root.destroy()

  • 根窗口(Root Window):是所有Tkinter应用程序的主窗口,通常由Tk()类实例化。它是其他所有窗口部件的父窗口。
  • 主循环 root.mainloop():(1)启动Tkinter的主事件循环,使应用程序保持运行并处理所有用户交互(如:鼠标点击、键盘输入等)和窗口更新。(2)没有它,窗口不会响应用户输入或显示任何内容。(3)当用户关闭窗口时,自动结束事件处理循环并关闭程序,而不需要显示调用 root.destroy()。
  • 手动摧毁窗口 root.destroy():用于完全销毁 tkinter 主窗口。它不仅关闭窗口并终止应用程序的运行,包括停止所有与窗口相关的事件处理循环,并清理相关的资源(如:内存或文件句柄)。

4.2.1、主循环:root.mainloop()

在这里插入图片描述
点击(右)确定,(右)界面摧毁,(左)界面不会摧毁

import tkinter as tk
from tkinter import messagebox

def close_application():
    messagebox.showinfo("Info", "Closing the application...")

if __name__ == '__main__':
    root = tk.Tk()  # 创建主窗口
    root.title("Simple Tkinter App")  # 设置主窗口标题
    tk.Button(root, text="Click Me", command=close_application).pack(pady=20)  # 添加一个按钮
    root.mainloop()  # 启动主循环

4.2.2、手动摧毁窗口:root.destroy()

在这里插入图片描述
点击(右)确定,(右)界面摧毁,(左)界面同时摧毁

import tkinter as tk
from tkinter import messagebox

def close_application():
    messagebox.showinfo("Info", "Closing the application...")
    root.destroy()  # 手动关闭窗口并退出程序

if __name__ == '__main__':
	root = tk.Tk()  # 创建主窗口
	root.title("Simple Tkinter App")  # 设置主窗口标题
	tk.Button(root, text="Close", command=close_application).pack(pady=20)  # 添加一个关闭按钮
	root.mainloop()  # 启动主循环

4.3、项目实战

4.3.1、打开《文件》选择对话框:filedialog.askopenfilename()

在这里插入图片描述

import tkinter as tk
from tkinter import filedialog
import os

root = tk.Tk()		# 创建根窗口
root.withdraw()  	# 隐藏根窗口
file_path = filedialog.askopenfilename()		# 打开文件选择对话框
print("Selected file path:", file_path)			# 打印所选文件的路径

4.3.2、打开《文件夹》选择对话框:filedialog.askdirectory()

在这里插入图片描述

import tkinter as tk
from tkinter import filedialog

root = tk.Tk()		# 创建根窗口
root.withdraw()  	# 隐藏根窗口
folder_path = filedialog.askdirectory()			# 打开文件夹选择对话框
print("Selected folder path:", folder_path)		# 打印所选文件夹的路径
###########################################################################
"""读取文件夹中的所有 2D.tif 图像,并保存为3D.tif。"""
import os
import tifffile
import numpy as np

image_list = []		# 新建一个空列表
for filename in sorted(os.listdir(folder_path)):		  # 列举文件夹中的所有文件 + 排序 + 遍历。
    if filename.endswith('.tif'):						  # 提取以.tif结尾的图像文件。
        image_path = os.path.join(folder_path, filename)  # 路径拼接
        image = tifffile.imread(image_path)				  # 读取图像
        image_list.append(image)						  # 添加到图像列表

output_tif_path = "result.tif"
image_stack = np.stack(image_list, axis=0)		  # 将图像列表转换为三维数组
labeled_image = image_stack.astype(np.uint8)      # 数据类型转换为uint8
tifffile.imwrite(output_tif_path, labeled_image)  # 保存图像

4.3.3、消息框:tkinter.messagebox

官网:tkinter.messagebox— Tkinter 消息提示
源码: Lib/tkinter/messagebox.py
tkinter.messagebox模块:提供了多种弹出消息框的函数,用于在GUI应用程序中显示信息、警告、错误、提示用户进行确认等。消息框是模态的,将根据用户的选择返回 (True、False、OK、None、Yes、No) 的子集。

在这里插入图片描述

import tkinter as tk
from tkinter import messagebox


def show_message_boxes():
    root = tk.Tk()  # 创建主窗口
    root.withdraw()  # 隐藏主窗口
    root.lift()  # 提升窗口在最前面
    root.attributes('-topmost', True)  # 将窗口保持在最前面
    # root.after(0, lambda: root.attributes('-topmost', False))  # 保证消息框显示后可以被其他窗口覆盖

    messagebox.showinfo("信息", "这是一个信息消息框。")
    messagebox.showwarning("警告", "这是一个警告消息框。")
    messagebox.showerror("错误", "这是一个错误消息框。")

    result = messagebox.askquestion("问题", "这是一个问题消息框。")
    print(f"问题消息框:{
      
      result}")

    result = messagebox.askretrycancel("重试或取消", "这是一个重试/取消消息框。")
    print(f"重试/取消消息框:{
      
      result}")

    result = messagebox.askokcancel("确认", "这是一个确认消息框。")
    print(f"确认消息框:{
      
      result}")

    result = messagebox.askyesno("问题", "这是一个是/否消息框。")
    print(f"是否消息框:{
      
      result}")

    result = messagebox.askyesnocancel("问题", "这是一个是/否/取消消息框。")
    print(f"是/否/取消消息框:{
      
      result}")
    root.destroy()  # 用于销毁主窗口,从而退出程序。


if __name__ == '__main__':
    show_message_boxes()

4.3.4、滚动文本:tkinter.scrolledtext

官网:tkinter.scrolledtext— 滚动文本小部件
源码: Lib/tkinter/scrolledtext.py

tkinter.scrolledtext.ScrolledText:是 tkinter 库中的一个文本小部件,它带有一个内置的滚动条,使得可以方便地处理大量文本。这个组件可以用来创建带有垂直滚动条的文本输入或显示区域。

在这里插入图片描述

import tkinter as tk
from tkinter import scrolledtext

def main():
    root = tk.Tk()  # 创建主窗口
    root.title("ScrolledText 示例")  # 设置窗口标题
    root.geometry("400x300")  # 设置窗口大小

    # 创建ScrolledText小部件
    st = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=40, height=10, font=("Times New Roman", 12))
    st.pack(padx=10, pady=10)  # 将小部件放置在主窗口中,并设置外边距

    # 在ScrolledText中插入初始文本
    st.insert(tk.INSERT, "这是一个带滚动条的文本输入框。你可以在这里输入大量的文本内容,而不会超出显示区域。\n\n" \
                         "如果文本超出显示区域,会自动出现滚动条。")

    # 启动主事件循环
    root.mainloop()

if __name__ == "__main__":
    main()

4.3.5、选项卡界面:tkinter.ttk.Frame

在这里插入图片描述

import tkinter as tk
from tkinter import ttk

# 创建主窗口
root = tk.Tk()
root.title("嵌套 Tab 示例")
root.geometry("400x300")

# 创建主 Notebook (Tab 控件)
main_notebook = ttk.Notebook(root)
main_notebook.pack(expand=True, fill="both")

# 创建第一个主 Tab 的 Frame
tab1 = ttk.Frame(main_notebook)
main_notebook.add(tab1, text="主 Tab 1")

# 创建第二个主 Tab 的 Frame
tab2 = ttk.Frame(main_notebook)
main_notebook.add(tab2, text="主 Tab 2")

# 在第一个主 Tab 中创建嵌套的 Notebook
nested_notebook1 = ttk.Notebook(tab1)
nested_notebook1.pack(expand=True, fill="both")

# 创建第一个嵌套 Tab 的 Frame
nested_tab1_1 = ttk.Frame(nested_notebook1)
nested_notebook1.add(nested_tab1_1, text="嵌套 Tab 1-1")

# 创建第二个嵌套 Tab 的 Frame
nested_tab1_2 = ttk.Frame(nested_notebook1)
nested_notebook1.add(nested_tab1_2, text="嵌套 Tab 1-2")

# 在嵌套 Tab 中添加内容
label1 = ttk.Label(nested_tab1_1, text="这是嵌套 Tab 1-1")
label1.pack(pady=20)

label2 = ttk.Label(nested_tab1_2, text="这是嵌套 Tab 1-2")
label2.pack(pady=20)

# 在第二个主 Tab 中添加内容
label3 = ttk.Label(tab2, text="这是主 Tab 2,没有嵌套 Tab")
label3.pack(pady=20)

# 运行主循环
root.mainloop()

猜你喜欢

转载自blog.csdn.net/shinuone/article/details/140614751