Python - GUI编程



Python 提供了多种开发图形用户界面 (GUI) 的选项。最重要的特性如下所示。

  • Tkinter − Tkinter 是 Python 与 Python 自带的 Tk GUI 工具包的接口。我们将在本章中介绍此选项。

  • wxPython − 这是一个用于 wxWidgets GUI 工具包的开源 Python 接口。您可以在此处找到关于 WxPython 的完整教程 这里

  • PyQt − 这也是一个用于流行的跨平台 Qt GUI 库的 Python 接口。TutorialsPoint 有一个关于 PyQt5 的非常好的教程 这里

  • PyGTK − PyGTK 是一组用 Python 和 C 编写的 GTK + GUI 库的包装器。完整的 PyGTK 教程可在 这里找到。

  • PySimpleGUI − PySimpleGUI 是一个开源的跨平台 Python GUI 库。它旨在为基于 Python 的 Tkinter、PySide 和 WxPython 工具包创建桌面 GUI 提供统一的 API。有关详细的 PySimpleGUI 教程,请点击 这里

  • Pygame − Pygame 是一个流行的 Python 库,用于开发视频游戏。它是一个免费的、开源的、跨平台的 Simple DirectMedia Library (SDL) 包装器。有关 Pygame 的全面教程,请访问 这个链接

  • Jython − Jython 是一个针对 Java 的 Python 移植版本,它使 Python 脚本可以无缝访问本地计算机上的 Java 类库 //www.jython.cn

还有许多其他可用的接口,您可以在网上找到它们。

Tkinter编程

Tkinter 是 Python 的标准 GUI 库。Python 与 Tkinter 结合使用,提供了一种快速简便的创建 GUI 应用程序的方法。Tkinter 为 Tk GUI 工具包提供了一个强大的面向对象接口。

tkinter 包包含以下模块:

  • Tkinter − 主要 Tkinter 模块。

  • tkinter.colorchooser − 用于让用户选择颜色的对话框。

  • tkinter.commondialog − 此处列出的其他模块中定义的对话框的基类。

  • tkinter.filedialog − 常用对话框,允许用户指定要打开或保存的文件。

  • tkinter.font − 用于帮助处理字体的实用程序。

  • tkinter.messagebox − 访问标准 Tk 对话框。

  • tkinter.scrolledtext − 带有内置垂直滚动条的文本小部件。

  • tkinter.simpledialog − 基本对话框和便捷函数。

  • tkinter.ttk − Tk 8.5 中引入的主题部件集,为主 tkinter 模块中的许多经典部件提供了现代替代方案。

使用 Tkinter 创建 GUI 应用程序是一项简单的任务。您只需执行以下步骤。

  • 导入 Tkinter 模块。

  • 创建 GUI 应用程序主窗口。

  • 向 GUI 应用程序添加一个或多个上述部件。

  • 进入主事件循环以针对用户触发的每个事件采取行动。

示例

# note that module name has changed from Tkinter in Python 2
# to tkinter in Python 3

import tkinter
top = tkinter.Tk()

# Code to add widgets will go here...
top.mainloop()

这将创建一个如下窗口:

Tkinter Programming

当程序变得更复杂时,使用面向对象编程方法可以使代码更有条理。

import tkinter as tk
class App(tk.Tk):
   def __init__(self):
      super().__init__()

app = App()
app.mainloop()

Tkinter 部件

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

Tkinter 目前有 15 种类型的部件。我们在下表中介绍这些部件以及简要说明:

序号 操作符和描述
1 按钮 (Button)

Button 部件用于在应用程序中显示按钮。

2 画布 (Canvas)

Canvas 部件用于在应用程序中绘制形状,例如线条、椭圆、多边形和矩形。

3 复选框 (Checkbutton)

Checkbutton 部件用于将多个选项显示为复选框。用户可以一次选择多个选项。

4 输入框 (Entry)

Entry 部件用于显示单行文本字段,用于接受用户的输入值。

5 框架 (Frame)

Frame 部件用作容器部件来组织其他部件。

6 标签 (Label)

Label 部件用于为其他部件提供单行标题。它还可以包含图像。

7 列表框 (Listbox)

Listbox 部件用于向用户提供选项列表。

8 菜单按钮 (Menubutton)

Menubutton 部件用于在应用程序中显示菜单。

9 菜单 (Menu)

Menu 部件用于向用户提供各种命令。这些命令包含在 Menubutton 中。

10 消息 (Message)

Message 部件用于显示多行文本字段,用于接受用户的输入值。

11 单选按钮 (Radiobutton)

Radiobutton 部件用于将多个选项显示为单选按钮。用户一次只能选择一个选项。

12 滑块 (Scale)

Scale 部件用于提供滑块部件。

13 滚动条 (Scrollbar)

Scrollbar 部件用于向各种部件(例如列表框)添加滚动功能。

14 文本 (Text)

Text 部件用于显示多行文本。

15 顶级窗口 (Toplevel)

Toplevel 部件用于提供单独的窗口容器。

16 旋转框 (Spinbox)

Spinbox 部件是标准 Tkinter Entry 部件的一种变体,可用于从固定数量的值中进行选择。

17 窗格窗口 (PanedWindow)

PanedWindow 是一个容器部件,可以包含任意数量的窗格,这些窗格水平或垂直排列。

18 标签框架 (LabelFrame)

标签框架是一个简单的容器部件。其主要目的是充当复杂窗口布局的间隔符或容器。

19 tkMessageBox

此模块用于在应用程序中显示消息框。

让我们详细研究这些部件。

标准属性

让我们看看如何指定一些常见属性,例如大小、颜色和字体。

让我们简要地研究一下它们:

几何管理

所有 Tkinter 部件都可以访问特定的几何管理方法,这些方法的目的是在父部件区域内组织部件。Tkinter 公开了以下几何管理器类:pack、grid 和 place。

  • pack() 方法 − 此几何管理器在将部件放置到父部件之前,将部件组织成块。

  • grid() 方法 − 此几何管理器以表格状结构在父部件中组织部件。

  • place() 方法 − 此几何管理器通过将部件放置在父部件中的特定位置来组织部件。

让我们简要地研究一下几何管理方法:

简单对话框 (SimpleDialog)

tkinter 包中的 simpledialog 模块包括一个对话框类和便捷函数,用于通过模式对话框接受用户输入。它包含一个标签、一个输入部件和两个按钮“确定”和“取消”。这些函数是:

  • askfloat(title, prompt, **kw) − 接受浮点数。

  • askinteger(title, prompt, **kw) − 接受整数输入。

  • askstring(title, prompt, **kw) − 接受用户的文本输入。

以上三个函数提供对话框,提示用户输入所需类型的数值。如果按下“确定”,则返回输入;如果按下“取消”,则返回 None。

askinteger

from tkinter.simpledialog import askinteger
from tkinter import *
from tkinter import messagebox
top = Tk()

top.geometry("100x100")
def show():
   num = askinteger("Input", "Input an Integer")
   print(num)
   
B = Button(top, text ="Click", command = show)
B.place(x=50,y=50)

top.mainloop()

它将产生以下输出

SimpleDialog

askfloat

from tkinter.simpledialog import askfloat
from tkinter import *
top = Tk()

top.geometry("100x100")
def show():
   num = askfloat("Input", "Input a floating point number")
   print(num)
   
B = Button(top, text ="Click", command = show)
B.place(x=50,y=50)

top.mainloop()

它将产生以下输出

askfloat

askstring

from tkinter.simpledialog import askstring
from tkinter import *

top = Tk()

top.geometry("100x100")
def show():
   name = askstring("Input", "Enter you name")
   print(name)
   
B = Button(top, text ="Click", command = show)
B.place(x=50,y=50)

top.mainloop()

它将产生以下输出

askstring

文件对话框模块 (FileDialog Module)

Tkinter 包中的 filedialog 模块包括一个 FileDialog 类。它还定义了便捷函数,使用户能够执行打开文件、保存文件和打开目录活动。

  • filedialog.asksaveasfilename()
  • filedialog.asksaveasfile()
  • filedialog.askopenfilename()
  • filedialog.askopenfile()
  • filedialog.askdirectory()
  • filedialog.askopenfilenames()
  • filedialog.askopenfiles()

askopenfile

此函数允许用户从文件系统中选择所需的文件。文件对话框窗口具有“打开”和“取消”按钮。按下“确定”时返回文件名及其路径;如果按下“取消”,则返回 None。

from tkinter.filedialog import askopenfile
from tkinter import *

top = Tk()

top.geometry("100x100")
def show():
   filename = askopenfile()
   print(filename)
   
B = Button(top, text ="Click", command = show)
B.place(x=50,y=50)

top.mainloop()

它将产生以下输出

askopenfile

颜色选择器 (ColorChooser)

tkinter 包中包含的 colorchooser 模块具有允许用户通过颜色对话框选择所需颜色对象的功能。askcolor() 函数显示颜色对话框,其中包含预定义的颜色样本以及通过设置 RGB 值来选择自定义颜色的功能。该对话框返回所选颜色的 RGB 值元组及其十六进制值。

from tkinter.colorchooser import askcolor
from tkinter import *

top = Tk()

top.geometry("100x100")
def show():
   color = askcolor()
   print(color)
   
B = Button(top, text ="Click", command = show)
B.place(x=50,y=50)

top.mainloop()

它将产生以下输出

ColorChooser
((0, 255, 0), '#00ff00')

ttk 模块

ttk 代表 Tk 主题部件。ttk 模块从 Tk 8.5 开始引入。它提供了额外的优势,包括在 X11 下的反锯齿字体渲染和窗口透明度。它为 Tkinter 提供了主题和样式支持。

ttk 模块捆绑了 18 个部件,其中 12 个已存在于 Tkinter 中。导入 ttk 会使用新的部件覆盖这些部件,这些部件旨在在所有平台上都具有更好、更现代的外观。

ttk 中的 6 个新部件是:组合框 (Combobox)、分隔符 (Separator)、大小调整手柄 (Sizegrip)、树形视图 (Treeview)、笔记本 (Notebook) 和进度条 (ProgressBar)。

要覆盖基本的 Tk 部件,导入应遵循 Tk 导入:

from tkinter import *
from tkinter.ttk import *

原始 Tk 部件将自动被 tkinter.ttk 部件替换。它们是:按钮 (Button)、复选框 (Checkbutton)、输入框 (Entry)、框架 (Frame)、标签 (Label)、标签框架 (LabelFrame)、菜单按钮 (Menubutton)、窗格窗口 (PanedWindow)、单选按钮 (Radiobutton)、滑块 (Scale) 和滚动条 (Scrollbar)。

新的部件提供了跨平台更好的外观和感觉;但是,替换部件并不完全兼容。主要区别在于,诸如“fg”、“bg”以及其他与部件样式相关的部件选项不再存在于 Ttk 部件中。改为使用 ttk.Style 类以获得改进的样式效果。

ttk 模块中的新部件是:

  • 笔记本 (Notebook) − 此部件管理一系列“选项卡”,您可以在这些选项卡之间切换,从而更改当前显示的窗口。

  • 进度条 (ProgressBar) − 此部件用于通过使用动画显示进度或加载过程。

  • 分隔符 (Separator) − 使用分隔线分隔不同的部件。

  • 树形视图 (Treeview) − 此部件用于将项目组合成树状层次结构。每个项目都有一个文本标签、一个可选图像和一个可选数据值列表。

  • 组合框 (ComboBox) − 用于创建一个下拉选项列表,用户可以从中选择一个选项。

  • 大小调整手柄 (Sizegrip) − 在屏幕的右下角创建一个小的句柄,可用于调整窗口大小。

组合框部件 (Combobox Widget)

Python ttk 组合框显示下拉选项列表,并一次显示一个选项。它是 Entry 部件的子类。因此,它继承了 Entry 类的许多选项和方法。

语法

from tkinter import ttk

Combo = ttk.Combobox(master, values.......)

get() 函数用于检索组合框的当前值。

示例

from tkinter import *
from tkinter import ttk

top = Tk()
top.geometry("200x150")

frame = Frame(top)
frame.pack()

langs = ["C", "C++", "Java",
   "Python", "PHP"]
   
Combo = ttk.Combobox(frame, values = langs)
Combo.set("Pick an Option")
Combo.pack(padx = 5, pady = 5)
top.mainloop()

它将产生以下输出

Combobox Widget

进度条 (Progressbar)

ttk ProgressBar 部件及其如何用于创建加载屏幕或显示当前任务的进度。

语法

ttk.Progressbar(parent, orient, length, mode)

参数

  • 父容器 (Parent) − 将放置 ProgressBar 的容器,例如 root 或 Tkinter 框架。

  • 方向 (Orient) − 定义 ProgressBar 的方向,可以是垂直或水平。

  • 长度 (Length) − 通过采用整数值来定义 ProgressBar 的宽度。

  • 模式 (Mode) − 此参数有两个选项:确定性 (determinate) 和不确定性 (indeterminate)。

示例

下面给出的代码创建了一个带有三个按钮的进度条,这些按钮链接到三个不同的函数。

第一个函数将进度条中的“值”或“进度”递增 20。这是使用 step() 函数完成的,该函数采用整数值来更改进度量。(默认为 1.0)

第二个函数将进度条中的“值”或“进度”递减 20。

第三个函数打印出进度条中的当前进度级别。

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
frame= ttk.Frame(root)
def increment():
   progressBar.step(20)
   
def decrement():
   progressBar.step(-20)
   
def display():
   print(progressBar["value"])

progressBar= ttk.Progressbar(frame, mode='determinate')
progressBar.pack(padx = 10, pady = 10)

button= ttk.Button(frame, text= "Increase", command= increment)
button.pack(padx = 10, pady = 10, side = tk.LEFT)

button= ttk.Button(frame, text= "Decrease", command= decrement)
button.pack(padx = 10, pady = 10, side = tk.LEFT)
button= ttk.Button(frame, text= "Display", command= display)
button.pack(padx = 10, pady = 10, side = tk.LEFT)

frame.pack(padx = 5, pady = 5)
root.mainloop()

它将产生以下输出

Progressbar

笔记本 (Notebook)

Tkinter ttk 模块有一个新的有用部件,称为 Notebook。它是一组容器(例如框架),其中包含许多部件作为子部件。

每个“选项卡”或“窗口”都有一个与其关联的选项卡 ID,用于确定要切换到哪个选项卡。

您可以像在普通文本编辑器中一样在这些容器之间切换。

语法

notebook = ttk.Notebook(master, *options)

示例

本例将通过两种不同的方法向我们的 Notebook 小部件添加 3 个窗口。第一种方法使用 `add()` 函数,它简单地将新标签添加到末尾。另一种方法是 `insert()` 函数,它可以用于将标签添加到特定位置。

`add()` 函数接受一个必需参数,即要添加的容器小部件,其余参数是可选参数,例如 text(显示为标签标题的文本)、image 和 compound。

`insert()` 函数需要一个 `tab_id`,它定义了应插入的位置。`tab_id` 可以是索引值,也可以是字符串字面量,例如 "end",这将将其添加到末尾。

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
nb = ttk.Notebook(root)

# Frame 1 and 2
frame1 = ttk.Frame(nb)
frame2 = ttk.Frame(nb)

label1 = ttk.Label(frame1, text = "This is Window One")
label1.pack(pady = 50, padx = 20)
label2 = ttk.Label(frame2, text = "This is Window Two")
label2.pack(pady = 50, padx = 20)

frame1.pack(fill= tk.BOTH, expand=True)
frame2.pack(fill= tk.BOTH, expand=True)
nb.add(frame1, text = "Window 1")
nb.add(frame2, text = "Window 2")

frame3 = ttk.Frame(nb)
label3 = ttk.Label(frame3, text = "This is Window Three")
label3.pack(pady = 50, padx = 20)
frame3.pack(fill= tk.BOTH, expand=True)
nb.insert("end", frame3, text = "Window 3")
nb.pack(padx = 5, pady = 5, expand = True)

root.mainloop()

它将产生以下输出

Notebook

树状视图 (Treeview)

Treeview 小部件用于以表格或分层方式显示项目。它支持创建项目的行和列等功能,并允许项目具有子项,从而形成分层格式。

语法

tree = ttk.Treeview(container, **options)

选项

序号 选项 & 说明
1

columns

列名称列表

2

displaycolumns

列标识符列表(符号或整数索引),指定显示哪些数据列以及它们的显示顺序,或者字符串 "#all"。

3

height

可见行数。

4

padding

指定小部件的内部填充。可以是整数或包含 4 个值的列表。

5

selectmode

“extended”、“browse”或“none”之一。如果设置为“extended”(默认值),则可以选择多个项目。如果为“browse”,则一次只能选择一个项目。如果为“none”,则用户无法更改选择。

6

show

包含零个或多个以下值的列表,指定要显示的树的哪些元素。默认值为“tree headings”,即显示所有元素。

示例

在本例中,我们将创建一个简单的 Treeview ttk 小部件,并向其中填充一些数据。我们已经将一些数据存储在一个列表中,这些数据将在我们的 `read_data()` 函数中读取并添加到 Treeview 小部件。

我们首先需要定义一个列名称的列表/元组。我们省略了“Name”列,因为已经存在一个名称为空的(默认)列。

然后,我们将该列表/元组赋给 Treeview 中的 columns 选项,然后定义“headings”,其中 column 是实际的列,而 heading 只是显示小部件时显示的列标题。我们为每个列指定一个名称。“#0”是默认列的名称。

`tree.insert()` 函数具有以下参数:

  • Parent − 如果没有父项,则留空字符串。

  • Position − 我们想要添加新项目的位置。要追加,请使用 `tk.END`。

  • Iid − 项目 ID,用于稍后跟踪相关的项目。

  • Text − 我们将为其分配列表中的第一个值(名称)。

我们将把从列表中获得的其他两个值作为 Value 传递。

完整代码

import tkinter as tk
import tkinter.ttk as ttk
from tkinter import simpledialog

root = tk.Tk()
data = [
   ["Bobby",26,20000],
   ["Harrish",31,23000],
   ["Jaya",18,19000],
   ["Mark",22, 20500],
]
index=0
def read_data():
   for index, line in enumerate(data):
      tree.insert('', tk.END, iid = index,
         text = line[0], values = line[1:])
columns = ("age", "salary")

tree= ttk.Treeview(root, columns=columns ,height = 20)
tree.pack(padx = 5, pady = 5)

tree.heading('#0', text='Name')
tree.heading('age', text='Age')
tree.heading('salary', text='Salary')

read_data()
root.mainloop()

它将产生以下输出

Treeview

尺寸控制柄 (Sizegrip)

Sizegrip 小部件基本上是一个小的箭头状控制柄,通常放置在屏幕的右下角。在屏幕上拖动 Sizegrip 也会调整其附加到的容器的大小。

语法

sizegrip = ttk.Sizegrip(parent, **options)

示例

import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()
root.geometry("100x100")

frame = ttk.Frame(root)
label = ttk.Label(root, text = "Hello World")
label.pack(padx = 5, pady = 5)
sizegrip = ttk.Sizegrip(frame)
sizegrip.pack(expand = True, fill = tk.BOTH, anchor = tk.SE)
frame.pack(padx = 10, pady = 10, expand = True, fill = tk.BOTH)

root.mainloop()

它将产生以下输出

Sizegrip

分隔符 (Separator)

ttk Separator 小部件是一个非常简单的小部件,只有一个用途,那就是通过在小部件之间绘制一条线来帮助将小部件“分隔”成组/分区。我们可以更改此线(分隔符)的方向为水平或垂直,并更改其长度/高度。

语法

separator = ttk.Separator(parent, **options)

“orient”可以是 `tk.VERTICAL` 或 `tk.HORIZONTAL`,分别表示垂直和水平分隔符。

示例

这里我们创建了两个 Label 小部件,然后在它们之间创建了一个水平分隔符。

import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()
root.geometry("200x150")

frame = ttk.Frame(root)

label = ttk.Label(frame, text = "Hello World")
label.pack(padx = 5)

separator = ttk.Separator(frame,orient= tk.HORIZONTAL)
separator.pack(expand = True, fill = tk.X)

label = ttk.Label(frame, text = "Welcome To TutorialsPoint")
label.pack(padx = 5)

frame.pack(padx = 10, pady = 50, expand = True, fill = tk.BOTH)

root.mainloop()

它将产生以下输出

Separator
广告