Python GUI Cookbook —— 布局管理
2017-12-04 20:06
549 查看
原文链接:Python GUI Cookbook —— 布局管理
也可以垂直摆放
给之前的代码添加
给
还不知道 labels 右边的空间的大小
可以移除
对于网格管理器,其列的宽度取决于该列中最长的名字或 widget。
由于显示
column 0 的
添加下面的代码到我们的 Python 模块
接下来将
添加菜单项
如果你对这段代码有一点困惑的话,请不要担心,这仅仅是 tkinter 创建 menubar 的语法,并不很 Pythonic。
添加第二个菜单项
在两个菜单项中间添加分隔线
通过传
通过下面代码添加分隔线
接下来添加水平的第二个菜单
现在,我们的菜单项点击过后还没有反应,因此我们需要添加一些 commands 到菜单项
现在当我们点击 Exit,程序就会立刻退出。
添加第二个 Tab
在 Tab 1 中写一些内容
再加一些内容,好看清标题
给 Tab 2 也加上内容
点击
参考文献
Python GUI Programming Cookbook - Second Edition by Burkhard A. Meier
在标签框架中排列多个标签
LabelFrame可以让我们有组织的的设计 GUI。
[...] # Create a container to hold labels buttons_frame = ttk.LabelFrame(window, text=' Label in a Frame') buttons_frame.grid(column=0, row=7) # buttons_frame.grid(column=1, row=6) # Place labels into the container element ttk.Label(buttons_frame, text='Label1').grid(column=0, row=0, sticky=tk.W) ttk.Label(buttons_frame, text='Lable2').grid(column=1, row=0, sticky=tk.W) ttk.Label(buttons_frame, text='Label3').grid(column=2, row=0, sticky=tk.W) name_entered.focus() # Place cursor into name Entry # Start GUI window.mainloop()
也可以垂直摆放
# Create a container to hold labels buttons_frame = ttk.LabelFrame(window, text=' Label in a Frame') buttons_frame.grid(column=0, row=7) # buttons_frame.grid(column=1, row=6) # Place labels into the container element ttk.Label(buttons_frame, text='Label1').grid(column=0, row=0, sticky=tk.W) ttk.Label(buttons_frame, text='Lable2').grid(column=0, row=1, sticky=tk.W) ttk.Label(buttons_frame, text='Label3').grid(column=0, row=2, sticky=tk.W) name_entered.focus() # Place cursor into name Entry # Start GUI window.mainloop()
使用填充增加 widget 周围的空间
tkinter 因 GUI 丑陋而闻名,然而这种情况在版本号 8.5 后发生了巨大的变化。Python 3.6 带有 tkinter 8.6。给之前的代码添加
padx和
pady。
[...] buttons_frame.grid(column=0, row=7, padx=20, pady=40) [...]
给
LabelFrame包含的标签添加一些空间
[...] ttk.Label(buttons_frame, text='Lable2').grid(column=0, row=1) ttk.Label(buttons_frame, text='Label3').grid(column=0, row=2) for child in buttons_frame.winfo_children(): child.grid_configure(padx=8, pady=4) name_entered.focus() # Place cursor into name Entry # Start GUI window.mainloop()
grid_configure()可以让我们能够在主循环显示 UI 之前修改它们。所以不必在首次创建 widget 时硬编码这些值。
winfo_children()返回 buttons_frame 的子 widgets。
还不知道 labels 右边的空间的大小
[...] # Place labels into the container element ttk.Label(buttons_frame, text='Label1 -- sooooooo much looooooooonger...').grid(column=0, row=0) ttk.Label(buttons_frame, text='Lable2').grid(column=0, row=1) ttk.Label(buttons_frame, text='Label3').grid(column=0, row=2) [...]
可以移除
LabelFrme的名字。看看 padx 的效果
[...] buttons_frame = ttk.LabelFrame(window, text='') [...]
widgets 动态扩展 GUI
你可能已经看到了 widget 能够自动扩展所需空间以便直观地显示文本。对于网格管理器,其列的宽度取决于该列中最长的名字或 widget。
由于显示
LaqbelFrame标题的文本属性比上面的
Enter a name:label 和 textbox entry 都长,所以这两个 widget 都依据新宽度,动态地中心对齐到 column 0。
column 0 的
Checkbutton和
Radiobutton没有中心对齐,因为使用了
sticky=tk.W属性。
通过在框架中放入框架来组织 GUI widgets
这里我们将创建一个顶层框架来包含其他 widget添加下面的代码到我们的 Python 模块
#!/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") # We are creating a container frame to hold all other widgets mighty = ttk.LabelFrame(window, text=' Mighty Python ') mighty.grid(column=0, row=0, padx=8, pady=4) [...]
接下来将
mighty作为父
widget,替换
window。如下所示:
[...] # Modify adding a Label using mighty as the parent instead of window a_label = ttk.Label(mighty, text = 'Enter a number:') a_label.grid(column=0, row=0) [...]
创建菜单栏
首先需要从 tkinter 中导入 Menu 类#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk from tkinter import scrolledtext from tkinter import Menu # Create instance window = tk.Tk() [...]
添加菜单项
[...] # Creating a Menu Bar menu_bar = Menu(window) window.config(menu=menu_bar) # Creating menu and add menu items file_menu = Menu(menu_bar) # create File menu file_menu.add_command(label='New') # add file menu item menu_bar.add_cascade(label='File', menu=file_menu) # add File menu to menu bar name_entered.focus() # Place cursor into name Entry # Start GUI window.mainloop()
如果你对这段代码有一点困惑的话,请不要担心,这仅仅是 tkinter 创建 menubar 的语法,并不很 Pythonic。
添加第二个菜单项
[...] # Creating a Menu Bar menu_bar = Menu(window) window.config(menu=menu_bar) # Creating menu and add menu items file_menu = Menu(menu_bar) # create File menu file_menu.add_command(label='New') # add file menu item file_menu.add_command(label='Exit') menu_bar.add_cascade(label='File', menu=file_menu) # add File menu to menu bar name_entered.focus() # Place cursor into name Entry # Start GUI window.mainloop()
在两个菜单项中间添加分隔线
通过传
tearoff属性到菜单的构造器,移除第一个 dashed line
通过下面代码添加分隔线
[...] # Creating menu and add menu items file_menu = Menu(menu_bar, tearoff=0) # create File menu file_menu.add_comm 105f5 and(label='New') # add file menu item file_menu.add_separator() file_menu.add_command(label='Exit') menu_bar.add_cascade(label='File', menu=file_menu) # add File menu to menu bar name_entered.focus() # Place cursor into name Entry # Start GUI window.mainloop()
接下来添加水平的第二个菜单
[...] # Adding another Menu to the Menu Bar and an item help_menu = Menu(menu_bar, tearoff=0) help_menu.add_command(label='About') menu_bar.add_cascade(label='Help', menu=help_menu) [...]
现在,我们的菜单项点击过后还没有反应,因此我们需要添加一些 commands 到菜单项
[...] # Exit GUI cleanly def _quit(): window.quit() window.destroy() exit() # Creating a Menu Bar menu_bar = Menu(window) window.config(menu=menu_bar) # Creating menu and add menu items file_menu = Menu(menu_bar, tearoff=0) # create File menu file_menu.add_command(label='New') # add file menu item file_menu.add_separator() file_menu.add_command(label='Exit', command=_quit) menu_bar.add_cascade(label='File', menu=file_menu) # add File menu to menu bar [...]
现在当我们点击 Exit,程序就会立刻退出。
创建选项卡式 widgets
创建一个新的 Python 模块#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk window = tk.Tk() # Create instance window.title('Python GUI') # Add a title tabControl = ttk.Notebook(window) # Create Tab Control tab1 = ttk.Frame(tabControl) # Create a Tab tabControl.add(tab1, text='Tab 1') # Add the Tab tabControl.pack(expand=1, fill='both') # Pack to make visible window.mainloop()
添加第二个 Tab
#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk window = tk.Tk() # Create instance window.title('Python GUI') # Add a title tabControl = ttk.Notebook(window) # Create Tab Control tab1 = ttk.Frame(tabControl) # Create a Tab tabControl.add(tab1, text='Tab 1') # Add the Tab tab2 = ttk.Frame(tabControl) # Create second Tab tabControl.add(tab2, text='Tab 2') # Add second Tab tabControl.pack(expand=1, fill='both') # Pack to make visible window.mainloop()
在 Tab 1 中写一些内容
#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk window = tk.Tk() # Create instance window.title('Python GUI') # Add a title tabControl = ttk.Notebook(window) # Create Tab Control tab1 = ttk.Frame(tabControl) # Create a Tab tabControl.add(tab1, text='Tab 1') # Add the Tab tab2 = ttk.Frame(tabControl) # Create second Tab tabControl.add(tab2, text='Tab 2') # Add second Tab tabControl.pack(expand=1, fill='both') # Pack to make visible # LabelFrame using tab1 as the parent mighty = ttk.LabelFrame(tab1, text=' Mighty Python ') mighty.grid(column=0, row=0, padx=8, pady=4) # Label using mighty as the parent a_label = ttk.Label(mighty, text=' Enter a number: ') a_label.grid(column=0, row=0, sticky='W') window.mainloop()
再加一些内容,好看清标题
#!/usr/bin/env python3 import tkinter as tk from tkinter import ttk from tkinter import scrolledtext window = tk.Tk() # Create instance window.title('Python GUI') # Add a title tabControl = ttk.Notebook(window) # Create Tab Control tab1 = ttk.Frame(tabControl) # Create a Tab tabControl.add(tab1, text='Tab 1') # Add the Tab tab2 = ttk.Frame(tabControl) # Create second Tab tabControl.add(tab2, text='Tab 2') # Add second Tab tabControl.pack(expand=1, fill='both') # Pack to make visible # LabelFrame using tab1 as the parent mighty = ttk.LabelFrame(tab1, text=' Mighty Python ') mighty.grid(column=0, row=0, padx=8, pady=4) # Label using mighty as the parent a_label = ttk.Label(mighty, text=' Enter a number: ') a_label.grid(column=0, row=0, sticky='W') # Modified Button click Event Function def click_me(): action.configure(text='Hello ' + name.get() + ' ' + number_chosen.get()) # Adding a Textbox Entry widget name = tk.StringVar() name_entered = ttk.Entry(mighty, width=12, textvariable=name) name_entered.grid(column=0, row=1, sticky='W') # column 0 # Adding a Button action = ttk.Button(mighty, text="Click Me!", command=click_me) action.grid(column=2, row=1, sticky='W') # change column to 2 ttk.Label(mighty, text='Choose a number:').grid(column=1, row=0, sticky='W') number = tk.StringVar() number_chosen = ttk.Combobox(mighty, width=12, textvariable=number, state='readonly') number_chosen['values'] = (1, 2, 4, 42, 100) number_chosen.grid(column=1, row=1, sticky='W') # Combobox in column 1 number_chosen.current(4) # Using a scrlled text control scrol_w = 30 scrol_h = 3 scr = scrolledtext.ScrolledText(mighty, width=scrol_w, height=scrol_h, wrap=tk.WORD) scr.grid(column=0, sticky='WE', columnspan=3) window.mainloop()
给 Tab 2 也加上内容
[...] # Creating three checkbuttons chVarDis = tk.IntVar() check1 = tk.Checkbutton(snake, text='Disabled', variable=chVarDis, state='disabled') check1.select() check1.grid(column=0, row=0, sticky='W') chVarUn = tk.IntVar() check2 = tk.Checkbutton(snake, text='UnChecked', variable=chVarUn) check2.deselect() check2.grid(column=1, row=0, sticky='W') chVarEn = tk.IntVar() check3 = tk.Checkbutton(snake, text='Enabled', variable=chVarEn) check3.deselect() check3.grid(column=2, row=0, sticky='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 == 0: snake.configure(background=colors[0]) # now zero-based and using list elif radSel == 1: snake.configure(background=colors[1]) elif radSel == 2: snake.configure(background=colors[2]) # 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(snake, text=colors[col], variable=radVar, value=col, command=radCall) curRad.grid(column=col, row=1, sticky=tk.W) # Create a container to hold labels buttons_frame = ttk.LabelFrame(snake, text=' Labels in a Frame ') buttons_frame.grid(column=0, row=2) # buttons_frame.grid(column=1, row=6) # Place labels into the container element ttk.Label(buttons_frame, text='Label1').grid(column=0, row=0) ttk.Label(buttons_frame, text='Lable2').grid(column=0, row=1) ttk.Label(buttons_frame, text='Label3').grid(column=0, row=2) for child in buttons_frame.winfo_children(): child.grid_configure(padx=8, pady=4) window.mainloop()
点击
Radiobutton发现不起作用了,那么我们改变它们的功能
[...] # Radiobutton Callback def radCall(): radSel = radVar.get() if radSel == 0: snake.configure(text='Blue') # now zero-based and using list elif radSel == 1: snake.configure(text='Gold') elif radSel == 2: snake.configure(text='Red') [...]
使用网格布局管理器
如果我们不指明 row 的值,tkinter 会自动完成加 1 操作。参考文献
Python GUI Programming Cookbook - Second Edition by Burkhard A. Meier
相关文章推荐
- python 探索(四) Python CookBook 系统管理
- Python GUI Cookbook —— 线程与网络
- Python GUI Cookbook —— 创建 GUI 窗体并添加 Widgets
- Python图形GUI工具包tkinter如何调整元件在窗口中的位置几何布局管理
- Python GUI之tkinter布局管理
- python 探索(四) Python CookBook 系统管理
- 27-python_GUI-布局管理-事件处理
- Python面向对象和图形用户界面(二)---- GUI的基本框架 & 常用组件 & 布局管理
- Python图形GUI工具包tkinter如何调整元件在窗口中的位置几何布局管理
- Python GUI Cookbook —— Matplotlib 图表
- Python GUI Cookbook —— 定制 widgets
- Python cookbook(数据结构与算法)让字典保持有序的方法
- Python Cookbook学习记录 ch2_1_2013/10/27
- Python Cookbook学习记录 ch2_4/5_2013/10/27
- 【python cookbook】 替换字符串中的子串
- Python Cookbook 第二版 汉化版 [Recipe 1.7] 以单词或字符为单位对字符串进行反序排列
- Web.py Cookbook 简体中文版 - 管理自带webserver日志
- Python Cookbook 第二版 汉化版 [Recipe 1.5] 去除字符串末尾的空格
- Python cookbook(数据结构与算法)通过公共键对字典列表排序算法示例
- python 随机数(python cookbook)