在众多的控件中,边框控件Frame可以说是一个比较特别的一个。之所以这么说是因为Frame控件本身并不会被显示,功能只是为了将其他控件组织为一个整体以便进行布局管理。
上面的视频是之前说明Text控件时使用的。当时使用的是grid布局,为了保证摆放足够数量的按钮,将Text控件的columnspan设置为8:
# create text widget.
text = Text(root,
undo=True,
background="#a0ffa0", foreground="#000000",
height = 10)
text.grid(row=2 , column=0, columnspan=8)
但是这样做有一个不好的地方,就是Text控件的布局会受到按钮数量的影响,这不太好。本文使用Frame控件来解决这个问题。
首先构建包含第一行按钮的Frame控件:
edit_frame = Frame(root)
# change state function.
def change_state():
state = text.cget('state')
if state=='disabled':
text.config(state='normal')
text.config(background='#a0ffa0')
else:
text.config(state='disabled')
text.config(background='#efefef')
# change state button.
eb = Button(edit_frame,text="Enable", width=8, command=change_state)
eb.grid(row=0, column=0, sticky=E+W)
# delete selection.
def delete_selection():
try:
sel_from = text.index(SEL_FIRST)
sel_to = text.index(SEL_LAST)
# delete the selection.
text.delete(sel_from, sel_to)
except TclError:
pass
# delete selection button.
db = Button(edit_frame,text="Delete", width = 8, command=delete_selection)
db.grid(row=0, column=1, sticky=E+W)
# undo button
undo = Button(edit_frame, text='Undo', width = 8, command=lambda:text.edit_undo())
undo.grid(row=0, column = 2, sticky=E+W)
#redo button
redo = Button(edit_frame, text='Redo', width = 8, command=lambda:text.edit_redo())
redo.grid(row=0, column = 3, sticky=E+W)
edit_frame.grid(row=0, column=0, sticky=W)
代码比较长,但是大部分内容都和Text控件一文中的内容相同,不同的只有两点:
-
这点代码的首尾分别增加了构建edit_frame控件和使用grid方法对该控件进行布局的代码。
-
所有按钮的父控件都从root改为edit_frame。
接下来的格式按钮也以同样的方式处理:
format_frame = Frame(root)
# create fonts
fonts = [
Font(family='SimHei', size=20, weight=BOLD),
Font(family='SimHei', size=16),
Font(family='SimSun', size=12, weight=BOLD),
Font(family='SimSun', size=12)
]
# delete selection.
def format(index):
tag_name = 'Format' + str(index)
try:
sel_from = text.index(SEL_FIRST)
sel_to = text.index(SEL_LAST)
for name in text.tag_names():
text.tag_remove(name, sel_from, sel_to)
text.tag_add(tag_name, sel_from, sel_to)
# set format at first time.
range_count = len(text.tag_ranges(tag_name))
if range_count == 2:
text.tag_config(tag_name, font=fonts[index])
except TclError:
pass
# delete selection button.
for i in range(0, 4):
fb = Button(format_frame,
text="Format" + str(i),
width = 8,
command=lambda v=i : format(v))
fb.grid(row=1, column=i, sticky=E+W)
format_frame.grid(row=1, column=0, sticky=W)
使用Frame控件之后,在进行root窗口布局时,四个编辑按钮和四个格式按钮分别作为两个整体参加,因此生成Text控件时就不再需要考虑按钮的个数了:
# create text widget.
text = Text(root,
undo=True,
background="#a0ffa0", foreground="#000000",
height = 10)
text.grid(row=2 , column=0)
完整代码可以从下面的链接下载:
https://github.com/xueweiguo/TkinterPrimer/blob/master/Sample/18%20Frame.py
觉得本文有帮助?请分享给更多人。
阅读更多更新文章,请扫描下面二维码,关注微信公众号【面向对象思考】