Python GUI Cookbook —— 创建 GUI 窗体并添加 Widgets
2017-12-03 10:07
756 查看
原文链接:Python GUI Cookbook —— 创建 GUI 窗体并添加 Widgets
下面是代码:
这里我们从 tkinter 包导入了一个独立模块 ttk。ttk 模块有一些高级 widgets 能够让我们的 GUI 看起来更好看。ttk 代表 themed tk。
在这个实例中我们使用了
使用了网格布局管理器(grid layout manager)
可以发现窗体突然变小了好多,这是因为我们在窗体中添加了 widget,触发了优化,尽量使用小空间显示 widget(s)。
GUIs 是事件驱动的。点击按钮产生一个事件。我们将事件产生时会发生的事与回调函数绑定。通过
在 tkinter 中,我们需要声明
如果要限制用户,让他们只能选择程序中给出的选项,则要向构造器中传 Combobox 的 state 属性
将网格的
通过将 wrap 属性设置为
对于
运行程序会发现和上面的一样,但代码更简洁清晰。
参考文献
Python GUI Programming Cookbook - Second Edition by Burkhard A. Meier
创建第一个 Python GUI 程序
使用 Python 内置的 tkinter 模块,仅需 4 行代码就能创建一个 GUI。下面是代码:
#!/usr/bin/env python3 import tkinter as tk # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Start GUI window.mainloop()
防止窗口大小被调整
使用 tkinter 创建的 GUI 默认是能够调整大小的,但有时候我们希望窗体保持特定的大小,因此需要学习如何防止用户调整 GUI 大小。#!/usr/bin/env python3 import tkinter as tk # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Disable resizing the GUI by passing in False/False window.resizable(False, False) # Enable resizing x-dimension, disable y-dimension # window.resizable(True, False) # Start GUI window.mainloop()
在窗体中添加 label
label是一种简单的 widget,它能够向窗体中添加值(value),能够解释其他 widgets 的目的,提供额外的信息。
#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Add a Label ttk.Label(window, text = 'A Label').grid(column=0, row=0) # Start GUI window.mainloop()
这里我们从 tkinter 包导入了一个独立模块 ttk。ttk 模块有一些高级 widgets 能够让我们的 GUI 看起来更好看。ttk 代表 themed tk。
在这个实例中我们使用了
ttk.Label构造器设置文本属性(text property)
使用了网格布局管理器(grid layout manager)
可以发现窗体突然变小了好多,这是因为我们在窗体中添加了 widget,触发了优化,尽量使用小空间显示 widget(s)。
创建按钮并改变其文本属性
这里我们将添加一个buttonwidget,并使用该按钮(button)改变其他 widget 的属性。我们将学习 Python GUI 的回调函数(callback function)和事件处理机制。
#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Adding a Label that will get modified a_label = ttk.Label(window, text = 'A Label') a_label.grid(column=0, row=0) # Button click Event Function def click_me(): action.configure(text='** I have been Clicked! **') a_label.configure(foreground='red') a_label.configure(text='A Red Label') # Adding a Button action = ttk.Button(window, text='Click Me!', command=click_me) action.grid(column=1, row=0) # Start GUI window.mainloop()
GUIs 是事件驱动的。点击按钮产生一个事件。我们将事件产生时会发生的事与回调函数绑定。通过
ttk.Buttonwidget 的 command 属性调用它,注意调用时不需要圆括号,只需使用名字
click_me。
文本框 Text Box widgets
在 tkinter 中,只有一行的textboxwidget 被称为
Entry。
#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Adding a Label that will get modified a_label = ttk.Label(window, text = 'A Label') a_label.grid(column=0, row=0) # Modified Button click Event Function def click_me(): action.configure(text='Hello ' + name.get()) # Changing our Label ttk.Label(window, text='Enter a name: ').grid(column=0, row=0) # Adding a Text Box Entry widget name = tk.StringVar() name_entered = ttk.Entry(window, width=12, textvariable=name) name_entered.grid(column=0, row=1) # Adding a Button action = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=1, row=1) # Start GUI window.mainloop()
在 tkinter 中,我们需要声明
name变量为
tk.StringVar()。因为 tkinter 不是 Python。我们只是能够在 Python 中使用它,但它们并不是同种语言。
给 widget 设置焦点,禁用 widgets
只需调用focus()方法就能给一个 widget 设置焦点。
#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Adding a Label that will get modified a_label = ttk.Label(window, text = 'A Label') a_label.grid(column=0, row=0) # Modified Button click Event Function def click_me(): action.configure(text='Hello ' + name.get()) # Changing our Label ttk.Label(window, text='Enter a name:').grid(column=0, row=0) # Adding a Text Box Entry widget name = tk.StringVar() name_entered = ttk.Entry(window, width=12, textvariable=name) name_entered.grid(column=0, row=1) # Adding a Button action = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=1, row=1) action.configure(state='disabled') # Disable the Button Widget name_entered.focus_set() # Place cursor into name Entry # Start GUI window.mainloop()
组合框 Combo box widgets
下拉式组合框#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Adding a Label that will get modified a_label = ttk.Label(window, text = 'A Label') a_label.grid(column=0, row=0) # Modified Button click Event Function def click_me(): action.configure(text='Hello ' + name.get()+ ' ' + number_chosen.get()) # Changing our Label ttk.Label(window, text='Enter a name:').grid(column=0, row=0) # Adding a Textbox Entry widget name = tk.StringVar() name_entered = ttk.Entry(window, width=12, textvariable=name) name_entered.grid(column=0, row=1) # column 0 # Adding a Button action = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=2, row=1) # change column to 2 ttk.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 1 number_chosen.current(0) name_entered.focus() # Place cursor into name Entry # Start GUI window.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 1 number_chosen.current(0) [...]
创建具有不同初始状态的复选按钮
Checkbuttonwidgets
#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Adding a Label that will get modified a_label = ttk.Label(window, text = 'A Label') a_label.grid(column=0, row=0) # Modified Button click Event Function def click_me(): action.configure(text='Hello ' + name.get() + ' ' + number_chosen.get()) # Changing our Label ttk.Label(window, text='Enter a name:').grid(column=0, row=0) # Adding a Textbox Entry widget name = tk.StringVar() name_entered = ttk.Entry(window, width=12, textvariable=name) name_entered.grid(column=0, row=1) # column 0 # Adding a Button action = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=2, row=1) # change column to 2 # Creating three checkbuttons ttk.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 1 number_chosen.current(0) # Creating three checkbuttons chVarDis = 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 GUI window.mainloop()
将网格的
sticky属性设置为
tk.W意味着该 widget 向网格的西(west)面对齐。
使用单选按钮 radio button widgets
Radiobuttonwidgets
#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Adding a Label that will get modified a_label = ttk.Label(window, text = 'A Label') a_label.grid(column=0, row=0) # Modified Button click Event Function def click_me(): action.configure(text='Hello ' + name.get() + ' ' + number_chosen.get()) # Changing our Label ttk.Label(window, text='Enter a name:').grid(column=0, row=0) # Adding a Textbox Entry widget name = tk.StringVar() name_entered = ttk.Entry(window, width=12, textvariable=name) name_entered.grid(column=0, row=1) # column 0 # Adding a Button action = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=2, row=1) # change column to 2 ttk.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 1 number_chosen.current(0) # Creating three checkbuttons chVarDis = 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 function def 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 checkbutton chVarUn.trace('w', lambda unused0, unused1, unused2 : checkCallback()) chVarEn.trace('w', lambda unused0, unused1, unused2 : checkCallback()) # Radiobutton Globals COLOR1 = 'Blue' COLOR2 = 'Gold' COLOR3 = 'Red' # Radiobutton Callback def 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 variable radVar = 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 GUI window.mainloop()
使用滚动文本 scrolled text widgets
ScrolledText要比简单的
Entry大得多并且跨越多行。当文本大于 ScrolledText widget 的高度时,将自动启用垂直滚动条。
import tkinter as tk from tkinter import ttk from tkinter import scrolledtext [...] # Using a scrlled text control scrol_w = 40 scrol_h = 3 scr = 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 GUI window.mainloop()
通过将 wrap 属性设置为
tk.WORD来告诉
ScrolledTextwidget 通过单词来断行。 默认的是
tk.CHAR,以字符来断行。
对于
ScrolledTextwidget ,将网格的
columnspan属性设置为 3,能够让该 widget 横跨 3 列。默认情况下只有 1 列。
重构
可以发现在上面的代码中有很多冗余,这里我们将重构它们。#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk from tkinter import scrolledtext # Create instance window = tk.Tk() # Add a title window.title("My First Python GUI") # Adding a Label that will get modified a_label = ttk.Label(window, text = 'A Label') a_label.grid(column=0, row=0) # Modified Button click Event Function def click_me(): action.configure(text='Hello ' + name.get() + ' ' + number_chosen.get()) # Changing our Label ttk.Label(window, text='Enter a name:').grid(column=0, row=0) # Adding a Textbox Entry widget name = tk.StringVar() name_entered = ttk.Entry(window, width=12, textvariable=name) name_entered.grid(column=0, row=1) # column 0 # Adding a Button action = ttk.Button(window, text="Click Me!", command=click_me) action.grid(column=2, row=1) # change column to 2 ttk.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 1 number_chosen.current(0) # Creating three checkbuttons chVarDis = 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 function def 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 checkbutton chVarUn.trace('w', lambda unused0, unused1, unused2 : checkCallback()) chVarEn.trace('w', lambda unused0, unused1, unused2 : checkCallback()) # First, we change our Radiobutton globals variables into a list colors = ['Blue', 'Gold', 'Red'] # We have also changed the callback function to be zero-based, using list # instead of module-level global variables # Radiobutton Callback def 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 variable radVar = tk.IntVar() # Next we are selecting a non-existing index value for radVar radVar.set(99) # Now we are creating all three Radiobutton widgets within one loop for 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 control scrol_w = 40 scrol_h = 3 scr = 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 GUI window.mainloop()
运行程序会发现和上面的一样,但代码更简洁清晰。
参考文献
Python GUI Programming Cookbook - Second Edition by Burkhard A. Meier
相关文章推荐
- Python GUI Cookbook —— 定制 widgets
- Python GUI Cookbook —— Matplotlib 图表
- Python GUI Cookbook —— 布局管理
- python cookbook第三版学习笔记十二:类和对象(三)创建新的类或实例属性
- Python GUI Cookbook —— 线程与网络
- Python Cookbook 第二版 汉化版 [Recipe 1.5] 去除字符串末尾的空格
- GUI编程笔记(java)06:GUI窗体添加按钮并对按钮添加事件案例
- 【python cookbook】改变多行文本字符串的缩进
- python cookbook 3rd Python Cookbook(第3版)中文版:12.12 使用生成器代替线程
- Python Cookbook 第二版 汉化版 [00-1-Info]
- Python Cookbook 第二版 汉化版 [Recipe 16.4] 将参数与函数关联起来(Currying)
- python cookbook 读书笔记1(字符串处理1)
- Python Cookbook 第二版 汉化版 [Recipe 1.2] 字符与其对应的数字编码之间的转换
- Python Cookbook 4.1 复制(拷贝)对象(浅复制和深复制)
- Python Cookbook学习记录 ch3_3/4_2013/10/29
- python cook book第三版 读书笔记1(第一章)
- python cookbook 迭代器与生成器
- Python Cookbook(第2版)中文版
- Computing the Relative Path from One Directory to Another(Python cookbook 2-22)
- Python Cookbook(第3版)pdf