Tkinter笔记(1.3-1.4)
1.3 Label标签
Label控件可以用于显示文本或图像。Labels可以包含多行文本,但是只能用一种字体。对于文本,可以指定每行的宽度,或者在文本中适当的位置插入换行符。
例子中的Label使用wraplength=300来指定文本换行宽度,用justify=‘left’指定文本靠左对齐。Label的relief选项用法同frame。
在Label中显示图片
例子中涉及bitmap属性,作用是把图像映射到label中。这时,又遇到了老生常谈的问题,如何用相对路径访问文件。应该是很简单,但是我怎么一次也没成功过。用open测试了一下,子目录内的文件用“data/dataset1.csv”即可访问。
# 给出文件名和浮雕样式的数组
images = [('image1', 'sunken'), ('image2', 'sunken')]
frm2 = tk.Frame(root)
# 从文件新建PhotoImage对象,并将其运用到Label中,共2幅图。
img1 = tk.PhotoImage(file='images/%s.png' % images[0][0])
tk.Label(frm2, image=img1, relief='%s' % images[0][1]).pack(side='left', padx=5)
img2 = tk.PhotoImage(file='images/%s.png' % images[1][0])
tk.Label(frm2, image=img2, relief='%s' % images[1][1]).pack(side='right', padx=5)
frm2.pack()
根据网上的示例,用了PhotoImage类来生成图形对象img1和img2。将它们用在Label的image选项中,即可正常显示。
也尝试了BitmapImage方法,总是提示“_tkinter.TclError: format error in bitmap data”,也就是BitmapImage方法的输入文件格式错误。从tkinter文档中看到,BitmapImage类可以从字符串或文本文件中读取X11标准的bitmap,也就是说,给定的文件必须是数据文件,不能随随便便放个什么图片。这样就不如直接用photoimage方便了。
1.4 Buttons按钮
严格地讲,按钮就是能够响应鼠标或键盘事件的标签。你可以为按钮绑定call或callback方法,当按钮被**时调用对应的方法。按钮状态可以被设置为disabled,之后它就不会被用户**了。按钮控件可以包含文本或图像,文本可以扩展多行。按钮也可以被纳入tab group,这样就可以用TAB键来循环遍历它们。
不是所有的GUI编程者都知道按钮也可以设定浮雕效果。特殊地,浮雕flat和solid可以提供类似于工具栏的效果,而图标icons可以用来提供功能信息。但是运用某些浮雕效果时应当特别注意。例如,如果将一个按钮设置为sunken浮雕,那么**它时不会有什么外观上的变化。如果是这样,就要采取别的措施来描述“**”,例如改变背景色、字体或者颜色。
PTP书中举的例子是利用两个序列(边框线宽序列和浮雕效果序列),产生一个按钮阵列,并且点击任何一个按钮可以打印出按钮所用的浮雕和线宽。代码如下:
import tkinter as tk
# 将整个GUI封装为一个类
class GUI:
# 在初始化函数中就把需要的控件构建好,留出GUI所在的主窗口或toplevel窗口接口
def __init__(self, master=None):
# 生成一个None队列,None可以随后被替换为任意实例,这里是frame对象:5层frame。
frms = [None]*5
# 构建5层frame,每层frame内部依次排列label和6种relief的按钮。
for n in range(5):
# 构建一层frame
frms[n] = tk.Frame(master)
# 构建一个标签
lb = tk.Label(frms[n], text="bd = %d" % n)
lb.pack(side='left')
# 构建6个按钮
for rlf in ['flat', 'raised', 'sunken', 'ridge', 'groove', 'solid']:
# lambda函数的妙用**
btn = tk.Button(frms[n], text=rlf, relief=rlf, borderwidth=n,
command=lambda s=self, r=rlf, b=n: s.showborder(r, b),
width=10)
btn.pack(side='left', padx=10-n, pady=5-n)
frms[n].pack()
# 方法:显示浮雕效果和边框宽度
def showborder(self, rlf, bw):
print('%s:%d' % (rlf, bw))
# 创建主窗口实例
root = tk.Tk()
# 将GUI应用到主窗口
app = GUI(root)
# 主循环
root.mainloop()
值得一提的是lambda函数的使用。观察可知,这是在初始化函数中,调用类本身的方法。实际上,如果不是为了格式上的一致,也可以写为:
lambda r=rlf, b=n: self.showborder(r, b)
为按钮设定**函数的一般方法是就是command=XXX,其中XXX是函数名,直接使用,不加引号。