Python GUI Cookbook —— 创建 GUI 窗体并添加 Widgets
来源:互联网 发布:长虹电视网络设置在哪 编辑:程序博客网 时间:2024/05/21 00:18
原文链接:Python GUI Cookbook —— 创建 GUI 窗体并添加 Widgets
创建第一个 Python GUI 程序
使用 Python 内置的 tkinter 模块,仅需 4 行代码就能创建一个 GUI。
下面是代码:
#!/usr/bin/env python3import tkinter as tk# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Start GUIwindow.mainloop()
防止窗口大小被调整
使用 tkinter 创建的 GUI 默认是能够调整大小的,但有时候我们希望窗体保持特定的大小,因此需要学习如何防止用户调整 GUI 大小。
#!/usr/bin/env python3import tkinter as tk# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Disable resizing the GUI by passing in False/Falsewindow.resizable(False, False)# Enable resizing x-dimension, disable y-dimension# window.resizable(True, False)# Start GUIwindow.mainloop()
在窗体中添加 label
label
是一种简单的 widget,它能够向窗体中添加值(value),能够解释其他 widgets 的目的,提供额外的信息。
#!/usr/bin/env python3import tkinter as tkfrom tkinter import ttk# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Add a Labelttk.Label(window, text = 'A Label').grid(column=0, row=0)# Start GUIwindow.mainloop()
这里我们从 tkinter 包导入了一个独立模块 ttk。ttk 模块有一些高级 widgets 能够让我们的 GUI 看起来更好看。ttk 代表 themed tk。
- 在这个实例中我们使用了
ttk.Label
构造器设置文本属性(text property) - 使用了网格布局管理器(grid layout manager)
- 可以发现窗体突然变小了好多,这是因为我们在窗体中添加了 widget,触发了优化,尽量使用小空间显示 widget(s)。
创建按钮并改变其文本属性
这里我们将添加一个 button
widget,并使用该按钮(button)改变其他 widget 的属性。我们将学习 Python GUI 的回调函数(callback function)和事件处理机制。
#!/usr/bin/env python3import tkinter as tkfrom tkinter import ttk# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Adding a Label that will get modifieda_label = ttk.Label(window, text = 'A Label')a_label.grid(column=0, row=0)# Button click Event Functiondef click_me(): action.configure(text='** I have been Clicked! **') a_label.configure(foreground='red') a_label.configure(text='A Red Label')# Adding a Buttonaction = ttk.Button(window, text='Click Me!', command=click_me)action.grid(column=1, row=0)# Start GUIwindow.mainloop()
GUIs 是事件驱动的。点击按钮产生一个事件。我们将事件产生时会发生的事与回调函数绑定。通过 ttk.Button
widget 的 command 属性调用它,注意调用时不需要圆括号,只需使用名字 click_me
。
文本框 Text Box widgets
在 tkinter 中,只有一行的 textbox
widget 被称为 Entry
。
#!/usr/bin/env python3import tkinter as tkfrom tkinter import ttk# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Adding a Label that will get modifieda_label = ttk.Label(window, text = 'A Label')a_label.grid(column=0, row=0)# Modified Button click Event Functiondef click_me(): action.configure(text='Hello ' + name.get())# Changing our Labelttk.Label(window, text='Enter a name: ').grid(column=0, row=0)# Adding a Text Box Entry widgetname = tk.StringVar()name_entered = ttk.Entry(window, width=12, textvariable=name)name_entered.grid(column=0, row=1)# Adding a Buttonaction = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=1, row=1)# Start GUIwindow.mainloop()
在 tkinter 中,我们需要声明 name
变量为 tk.StringVar()
。因为 tkinter 不是 Python。我们只是能够在 Python 中使用它,但它们并不是同种语言。
给 widget 设置焦点,禁用 widgets
只需调用 focus()
方法就能给一个 widget 设置焦点。
#!/usr/bin/env python3import tkinter as tkfrom tkinter import ttk# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Adding a Label that will get modifieda_label = ttk.Label(window, text = 'A Label')a_label.grid(column=0, row=0)# Modified Button click Event Functiondef click_me(): action.configure(text='Hello ' + name.get())# Changing our Labelttk.Label(window, text='Enter a name:').grid(column=0, row=0)# Adding a Text Box Entry widgetname = tk.StringVar()name_entered = ttk.Entry(window, width=12, textvariable=name)name_entered.grid(column=0, row=1)# Adding a Buttonaction = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=1, row=1)action.configure(state='disabled') # Disable the Button Widgetname_entered.focus_set() # Place cursor into name Entry# Start GUIwindow.mainloop()
组合框 Combo box widgets
下拉式组合框
#!/usr/bin/env python3import tkinter as tkfrom tkinter import ttk# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Adding a Label that will get modifieda_label = ttk.Label(window, text = 'A Label')a_label.grid(column=0, row=0)# Modified Button click Event Functiondef click_me(): action.configure(text='Hello ' + name.get()+ ' ' + number_chosen.get())# Changing our Labelttk.Label(window, text='Enter a name:').grid(column=0, row=0)# Adding a Textbox Entry widgetname = tk.StringVar()name_entered = ttk.Entry(window, width=12, textvariable=name)name_entered.grid(column=0, row=1) # column 0# Adding a Buttonaction = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=2, row=1) # change column to 2ttk.Label(window, text='Choose a number:').grid(column=1, row=0)number = tk.StringVar()number_chosen = ttk.Combobox(window, width=12, textvariable=number)number_chosen['values'] = (1, 2, 4, 42, 100)number_chosen.grid(column=1, row=1) # Combobox in column 1number_chosen.current(0)name_entered.focus() # Place cursor into name Entry# Start GUIwindow.mainloop()
如果要限制用户,让他们只能选择程序中给出的选项,则要向构造器中传 Combobox 的 state 属性
[...]number = tk.StringVar()number_chosen = ttk.Combobox(window, width=12, textvariable=number, state='readonly')number_chosen['values'] = (1, 2, 4, 42, 100)number_chosen.grid(column=1, row=1) # Combobox in column 1number_chosen.current(0)[...]
创建具有不同初始状态的复选按钮
Checkbutton
widgets
#!/usr/bin/env python3import tkinter as tkfrom tkinter import ttk# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Adding a Label that will get modifieda_label = ttk.Label(window, text = 'A Label')a_label.grid(column=0, row=0)# Modified Button click Event Functiondef click_me(): action.configure(text='Hello ' + name.get() + ' ' + number_chosen.get())# Changing our Labelttk.Label(window, text='Enter a name:').grid(column=0, row=0)# Adding a Textbox Entry widgetname = tk.StringVar()name_entered = ttk.Entry(window, width=12, textvariable=name)name_entered.grid(column=0, row=1) # column 0# Adding a Buttonaction = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=2, row=1) # change column to 2# Creating three checkbuttonsttk.Label(window, text='Choose a number:').grid(column=1, row=0)number = tk.StringVar()number_chosen = ttk.Combobox(window, width=12, textvariable=number, state='readonly')number_chosen['values'] = (1, 2, 4, 42, 100)number_chosen.grid(column=1, row=1) # Combobox in column 1number_chosen.current(0)# Creating three checkbuttonschVarDis = tk.IntVar()check1 = tk.Checkbutton(window, text='Disabled', variable=chVarDis, state='disabled')check1.select()check1.grid(column=0, row=4, sticky=tk.W)chVarUn = tk.IntVar()check2 = tk.Checkbutton(window, text='UnChecked', variable=chVarUn)check2.deselect()check2.grid(column=1, row=4, sticky=tk.W)chVarEn = tk.IntVar()check3 = tk.Checkbutton(window, text='Enabled', variable=chVarEn)check3.select()check3.grid(column=2, row=4, sticky=tk.W)name_entered.focus() # Place cursor into name Entry# Start GUIwindow.mainloop()
将网格的 sticky
属性设置为 tk.W
意味着该 widget 向网格的西(west)面对齐。
使用单选按钮 radio button widgets
Radiobutton
widgets
#!/usr/bin/env python3import tkinter as tkfrom tkinter import ttk# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Adding a Label that will get modifieda_label = ttk.Label(window, text = 'A Label')a_label.grid(column=0, row=0)# Modified Button click Event Functiondef click_me(): action.configure(text='Hello ' + name.get() + ' ' + number_chosen.get())# Changing our Labelttk.Label(window, text='Enter a name:').grid(column=0, row=0)# Adding a Textbox Entry widgetname = tk.StringVar()name_entered = ttk.Entry(window, width=12, textvariable=name)name_entered.grid(column=0, row=1) # column 0# Adding a Buttonaction = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=2, row=1) # change column to 2ttk.Label(window, text='Choose a number:').grid(column=1, row=0)number = tk.StringVar()number_chosen = ttk.Combobox(window, width=12, textvariable=number, state='readonly')number_chosen['values'] = (1, 2, 4, 42, 100)number_chosen.grid(column=1, row=1) # Combobox in column 1number_chosen.current(0)# Creating three checkbuttonschVarDis = tk.IntVar()check1 = tk.Checkbutton(window, text='Disabled', variable=chVarDis, state='disabled')check1.select()check1.grid(column=0, row=4, sticky=tk.W)chVarUn = tk.IntVar()check2 = tk.Checkbutton(window, text='UnChecked', variable=chVarUn)check2.deselect()check2.grid(column=1, row=4, sticky=tk.W)chVarEn = tk.IntVar()check3 = tk.Checkbutton(window, text='Enabled', variable=chVarEn)check3.deselect()check3.grid(column=2, row=4, sticky=tk.W)# GUI callback functiondef checkCallback(*ignoredArgs): if chVarUn.get(): check3.configure(state='disabled') else: check3.configure(state='normal') if chVarEn.get(): check2.configure(state='disabled') else: check2.configure(state='normal')# trace the state of the two checkbuttonchVarUn.trace('w', lambda unused0, unused1, unused2 : checkCallback())chVarEn.trace('w', lambda unused0, unused1, unused2 : checkCallback())# Radiobutton GlobalsCOLOR1 = 'Blue'COLOR2 = 'Gold'COLOR3 = 'Red'# Radiobutton Callbackdef radCall(): radSel = radVar.get() if radSel == 1: window.configure(background=COLOR1) elif radSel == 2: window.configure(background=COLOR2) elif radSel == 3: window.configure(background=COLOR3)# Create three Radiobuttons using one variableradVar = tk.IntVar()rad1 = tk.Radiobutton(window, text=COLOR1, variable=radVar, value=1, command=radCall)rad1.grid(column=0, row=5, sticky=tk.W, columnspan=3)rad2 = tk.Radiobutton(window, text=COLOR2, variable=radVar, value=2, command=radCall)rad2.grid(column=1, row=5, sticky=tk.W, columnspan=3)rad3 = tk.Radiobutton(window, text=COLOR3, variable=radVar, value=3, command=radCall)rad3.grid(column=2, row=5, sticky=tk.W, columnspan=3)name_entered.focus() # Place cursor into name Entry# Start GUIwindow.mainloop()
使用滚动文本 scrolled text widgets
ScrolledText
要比简单的 Entry
大得多并且跨越多行。当文本大于 ScrolledText widget 的高度时,将自动启用垂直滚动条。
import tkinter as tkfrom tkinter import ttkfrom tkinter import scrolledtext[...]# Using a scrlled text controlscrol_w = 40scrol_h = 3scr = scrolledtext.ScrolledText(window, width=scrol_w, height=scrol_h, wrap=tk.WORD)scr.grid(column=0, columnspan=3)name_entered.focus() # Place cursor into name Entry# Start GUIwindow.mainloop()
- 通过将 wrap 属性设置为
tk.WORD
来告诉ScrolledText
widget 通过单词来断行。 默认的是tk.CHAR
,以字符来断行。 - 对于
ScrolledText
widget ,将网格的columnspan
属性设置为 3,能够让该 widget 横跨 3 列。默认情况下只有 1 列。
重构
可以发现在上面的代码中有很多冗余,这里我们将重构它们。
#!/usr/bin/env python3import tkinter as tkfrom tkinter import ttkfrom tkinter import scrolledtext# Create instancewindow = tk.Tk()# Add a titlewindow.title("My First Python GUI")# Adding a Label that will get modifieda_label = ttk.Label(window, text = 'A Label')a_label.grid(column=0, row=0)# Modified Button click Event Functiondef click_me(): action.configure(text='Hello ' + name.get() + ' ' + number_chosen.get())# Changing our Labelttk.Label(window, text='Enter a name:').grid(column=0, row=0)# Adding a Textbox Entry widgetname = tk.StringVar()name_entered = ttk.Entry(window, width=12, textvariable=name)name_entered.grid(column=0, row=1) # column 0# Adding a Buttonaction = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=2, row=1) # change column to 2ttk.Label(window, text='Choose a number:').grid(column=1, row=0)number = tk.StringVar()number_chosen = ttk.Combobox(window, width=12, textvariable=number, state='readonly')number_chosen['values'] = (1, 2, 4, 42, 100)number_chosen.grid(column=1, row=1) # Combobox in column 1number_chosen.current(0)# Creating three checkbuttonschVarDis = tk.IntVar()check1 = tk.Checkbutton(window, text='Disabled', variable=chVarDis, state='disabled')check1.select()check1.grid(column=0, row=4, sticky=tk.W)chVarUn = tk.IntVar()check2 = tk.Checkbutton(window, text='UnChecked', variable=chVarUn)check2.deselect()check2.grid(column=1, row=4, sticky=tk.W)chVarEn = tk.IntVar()check3 = tk.Checkbutton(window, text='Enabled', variable=chVarEn)check3.deselect()check3.grid(column=2, row=4, sticky=tk.W)# GUI callback functiondef checkCallback(*ignoredArgs): if chVarUn.get(): check3.configure(state='disabled') else: check3.configure(state='normal') if chVarEn.get(): check2.configure(state='disabled') else: check2.configure(state='normal')# trace the state of the two checkbuttonchVarUn.trace('w', lambda unused0, unused1, unused2 : checkCallback())chVarEn.trace('w', lambda unused0, unused1, unused2 : checkCallback())# First, we change our Radiobutton globals variables into a listcolors = ['Blue', 'Gold', 'Red']# We have also changed the callback function to be zero-based, using list# instead of module-level global variables# Radiobutton Callbackdef radCall(): radSel = radVar.get() if radSel == 1: window.configure(background=colors[0]) # now zero-based and using list elif radSel == 2: window.configure(background=colors[1]) elif radSel == 3: window.configure(background=colors[3])# Create three Radiobuttons using one variableradVar = tk.IntVar()# Next we are selecting a non-existing index value for radVarradVar.set(99)# Now we are creating all three Radiobutton widgets within one loopfor col in range(3): curRad = tk.Radiobutton(window, text=colors[col], variable=radVar, value=col, command=radCall) curRad.grid(column=col, row=5, sticky=tk.W)# Using a scrlled text controlscrol_w = 40scrol_h = 3scr = scrolledtext.ScrolledText(window, width=scrol_w, height=scrol_h, wrap=tk.WORD)scr.grid(column=0, columnspan=3)name_entered.focus() # Place cursor into name Entry# Start GUIwindow.mainloop()
运行程序会发现和上面的一样,但代码更简洁清晰。
参考文献
- Python GUI Programming Cookbook - Second Edition by Burkhard A. Meier
- Python GUI Cookbook —— 创建 GUI 窗体并添加 Widgets
- Python GUI Cookbook —— 定制 widgets
- Python GUI Cookbook —— 布局管理
- PyQt4 Python GUI窗体应用程序
- javaSE基础编程——GUI窗体
- python—Tkinter GUI编程
- GUI--移植3--添加并配置触摸屏到uc/gui
- Java_基础—GUI(创建一个窗口并显示/布局管理器)
- 黑马程序员——GUI(1)基本窗体组件
- python GUI编程——Scrollbar&&Listbox
- Python GUI——Tkinter~简单入门
- python——gui之entry
- Python GUI
- python gui
- Python GUI
- Python GUI
- python-gui
- python GUI
- PASCAL VOC数据集介绍
- 阿里的27个项目资源带你走进Github世界!
- SpringCloud教程第四篇:分布式配置中心
- tensorflow的slim换地址了
- python连接mysql
- Python GUI Cookbook —— 创建 GUI 窗体并添加 Widgets
- Java中this和super的区别
- 自定义类型---->结构体,枚举,联合体
- 阿里巴巴Java开发手册评述
- 11月英语学习总结
- 对卷积核的相关解释论文和实验
- 为什么要学习HashMap的底层原理?
- 神经网络和深度学习-第一周深度学习概论-第一节:欢迎来到深度学习工程师微专业
- 中国大学 MOOC 课程 《Python 语言程序设计》第五周课后习题