简介
简介
- Tcl
- 动态解释型编程语言
- 可独立执行,多嵌入C程序中作为脚本引擎,或者作为使用Tk工具包的接口
- Tcl库可以创建一个或多个Tcl解释器实例,然后在这些实例上运行C或Tcl命令和脚本
- 每个解释器有一个事件队列,接受事件并处理他们
- Tk
- 用C语言实现的一个Tcl包
- 添加了自定义命令创建和操作GUI组件
- 是唯一一个专门为高级动态语言(如 Python、 Tcl、 Ruby、 Perl 等)设计的跨平台(Windows、 Mac、 Unix)图形用户界面工具包
- Tk的组件可以支持丰富的自定义,但风格比较过时
- 使用Tcl的事件队列生成和处理GUI事件
- Ttk
- 主体化Tk(Themed Tk)
- 相比经典Tk,提供更新的Tk组件,提供更好的样式
- Tkinter是Python 的标准 Tk GUI 工具包的接口,可以实现简单的跨平台GUI程序
- Tkinter 是 Python 内置的标准 GUI 库,无需额外安装
- Python2.x 版本使用的库名为 Tkinter
- Python3.x 版本使用的库名为 tkinter
参考
Python GUI编程(Tkinter) 菜鸟教程
TkDocs
TkDocs Tutorial
TkDocs reference
Python interface to Tcl/Tk
Tk Commands
Button
Python2.x vs Python3.x
Python2.x | Python3.x |
---|---|
Tkinter | tkinter |
ScrolledText | tkinter.scrolledtext |
ttk | tkinter.ttk |
tkMesageBox | tkinter.messagebox |
tkAxxBxx | tkinter.axxbxx |
- 导入tkinter,处理下python2和python3的差异
- 继承Frame Class,初始化Frame,初始化其他参数
- 获取屏幕大小,设置App大小为屏幕大小的百分之80
- 设置App标题
- 以自身为master创建控件,配置控件,监听处理控件事件
- 放置控件,pack()或grid()或place()
- 程序进入主循环,显示程序mainloop()
#!/usr/bin/env python
# -*- coding: utf-8 -*-import sysif sys.version_info[0] < 3:import Tkinter as tk ## Python 2.ximport tkFont as tk_fontimport tkMessageBox as tk_messagebox
else:import tkinter as tk ## Python 3.ximport tkinter.font as tk_fontimport tkinter.messagebox as tk_messageboxclass App(tk.Frame):def __init__(self, master=None):tk.Frame.__init__(self, master)self.font = tk_font.Font(family='Helvetica', size=36, weight='bold')self.config(bg='black')self.setScreenSize()# self = tk.Frame()# self.master = tk.Tk()self.master.title("ButtonTest")self.createWidgets()def setScreenSize(self):ratio = 0.8screen_h = self.master.winfo_screenheight()screen_w = self.master.winfo_screenwidth()# print(screen_h, screen_w)app_h = round(screen_h * ratio)app_w = round(screen_w * ratio)y = round(screen_h * (1 - ratio) / 2.0)x = round(screen_w * (1 - ratio) / 2.0)geometry = '' + str(app_w) + 'x' + str(app_h) + '+' + str(x) + '+' + str(y)# print(geometry)self.master.geometry(geometry)def createWidgets(self):self.button = tk.Button(self, text="hello", bg="red", fg="#0000FF", font=self.font, command=self.helloCallBack)self.draw()def helloCallBack(self):tk_messagebox.showinfo("Title", "Message")def draw(self):self.pack(padx=50, pady=50)self.button.pack(padx=50, pady=50)self.mainloop()if __name__ == '__main__':App()
Layout
我们尝试实现一个如下的布局来学习tkinter的布局
pack
pack CMD
anchor + side定位
- anchor
- 组件放在父组件的什么位置,上下左右搭配8个方向,然后还有中间
- s要搭配side=bottom,不然跟n效果一样
- side
- 放在上一个组件的上下左右,比如left,就是放在上一个组件左边
#!/usr/bin/env python
# -*- coding: utf-8 -*-import sys
import randomif sys.version_info[0] < 3:import Tkinter as tk ## Python 2.ximport tkMessageBox as tk_messagebox
else:import tkinter as tk ## Python 3.ximport tkinter.messagebox as tk_messageboxclass App(tk.Frame):def __init__(self, master=None):tk.Frame.__init__(self, master)self.master.title("pack")self.font = 'Times 20 bold'self.config(height=600, width=600)self.createWidgets()def createWidgets(self):self.createFrame1()self.createFrame2()self.createFrame3()self.draw()def createFrame1(self):frame = tk.Frame(self, height=200, width=800)self.createBtn(frame, anchor='NW')self.createBtn(frame, anchor='N')self.createBtn(frame, anchor='NE')frame.pack()frame.pack_propagate(0)def createFrame2(self):frame = tk.Frame(self, height=200, width=800)self.createBtn(frame, anchor='W', side='left')self.createBtn(frame, anchor='CENTER', side=None)self.createBtn(frame, anchor='E', side='right')frame.pack()frame.pack_propagate(0)def createFrame3(self):frame = tk.Frame(self, height=200, width=800)self.createBtn(frame, anchor='SW', side='bottom')self.createBtn(frame, anchor='S', side='bottom')self.createBtn(frame, anchor='SE', side='bottom')frame.pack(side='bottom')frame.pack_propagate(0)def createBtn(self, parent, anchor, side='top'):bg = self.getRandColor()frame = tk.Frame(parent, height=200, width=200, bg=bg)button = tk.Button(frame, text=anchor)frame.pack(side='left')frame.pack_propagate(0)if(anchor == 'CENTER'):button.pack(padx=50, pady=50, expand=True)else:button.pack(anchor=anchor.lower(), side=side)def getRandColor(self):return '#' + self.getRandRGB() + self.getRandRGB() + self.getRandRGB()def getRandRGB(self):return '{:02X}'.format(random.randint(0, 255))def helloCallBack(self):tk_messagebox.showinfo("Title", "Message")def draw(self):self.pack()self.pack_propagate(0)self.mainloop()if __name__ == '__main__':App()
假设我只想用一个Frame,就会显得很奇怪
#!/usr/bin/env python
# -*- coding: utf-8 -*-import sys
import randomif sys.version_info[0] < 3:import Tkinter as tk ## Python 2.ximport tkMessageBox as tk_messagebox
else:import tkinter as tk ## Python 3.ximport tkinter.messagebox as tk_messageboxclass App(tk.Frame):def __init__(self, master=None):tk.Frame.__init__(self, master)self.master.title("pack")self.font = 'Times 20 bold'self.config(height=600, width=600)self.createWidgets()def createWidgets(self):self.createBtn(self, anchor='W', side='left')self.createBtn(self, anchor='NW', side='top')self.createBtn(self, anchor='N', side='top')self.createBtn(self, anchor='NE', side='top')self.createBtn(self, anchor='CENTER', side='bottom')self.createBtn(self, anchor='SW', side='bottom')self.createBtn(self, anchor='S', side='bottom')self.createBtn(self, anchor='SE', side='bottom')self.createBtn(self, anchor='E', side='right')self.draw()def createBtn(self, parent, anchor, side='top'):bg = self.getRandColor()button = tk.Button(parent, text=anchor, bg=self.getRandColor())if(anchor == 'CENTER'):button.pack(padx=50, pady=50, expand=True)else:button.pack(anchor=anchor.lower(), side=side)def getRandColor(self):return '#' + self.getRandRGB() + self.getRandRGB() + self.getRandRGB()def getRandRGB(self):return '{:02X}'.format(random.randint(0, 255))def helloCallBack(self):tk_messagebox.showinfo("Title", "Message")def draw(self):self.pack()self.pack_propagate(0)self.mainloop()if __name__ == '__main__':App()
place
- x,y
- 绝对定位
- relx,rely
- 相对定义,relx=0就是最左,relx=1就是最右
#!/usr/bin/env python
# -*- coding: utf-8 -*-import sys
import randomif sys.version_info[0] < 3:import Tkinter as tk ## Python 2.ximport tkMessageBox as tk_messagebox
else:import tkinter as tk ## Python 3.ximport tkinter.messagebox as tk_messageboxclass App(tk.Frame):def __init__(self, master=None):tk.Frame.__init__(self, master)self.master.title("pack")self.font = 'Times 20 bold'self.config(height=600, width=600)self.createWidgets()def createWidgets(self):self.createBtn(0, 0, 'nw')self.createBtn(0.5, 0, 'n')self.createBtn(1, 0, 'ne')self.createBtn(0, 0.5, 'w')self.createBtn(0.5, 0.5, 'center')self.createBtn(1, 0.5, 'e')self.createBtn(0, 1, 'sw')self.createBtn(0.5, 1, 's')self.createBtn(1, 1, 'se')self.draw()def createBtn(self, x, y, anchor):button = tk.Button(self, text='(' + str(x) + ', ' + str(y) + ')', bg=self.getRandColor())button.place(relx=x, rely=y, anchor=anchor)def getRandColor(self):return '#' + self.getRandRGB() + self.getRandRGB() + self.getRandRGB()def getRandRGB(self):return '{:02X}'.format(random.randint(0, 255))def draw(self):self.pack()self.pack_propagate(0)self.mainloop()if __name__ == '__main__':App()
grid
这个就是css中的table,比较简单了
- row,rowspan
- column,columnspan
- sticky
- 组件大小小于父组件时怎么填充父组件
- nesw:水平垂直都拉伸填充
- ns:垂直填充
- ew:水平填充
#!/usr/bin/env python
# -*- coding: utf-8 -*-import sys
import randomif sys.version_info[0] < 3:import Tkinter as tk ## Python 2.ximport tkMessageBox as tk_messagebox
else:import tkinter as tk ## Python 3.ximport tkinter.messagebox as tk_messageboxclass App(tk.Frame):def __init__(self, master=None):tk.Frame.__init__(self, master)self.master.title("pack")self.font = 'Times 20 bold'# self.config(height=600, width=600)self.createWidgets()def createWidgets(self):self.createBtn(0, 0, 1, 2)self.createBtn(0, 2, 2, 1)self.createBtn(1, 0, 2, 1)self.createBtn(1, 1)self.createBtn(2, 1, 1, 2)self.draw()def createBtn(self, row, col, rowspan = 1, colspan = 1):button = tk.Button(self, text='(' + str(row) + ', ' + str(col) + ')', bg=self.getRandColor(), width=20, height=8)button.grid(row=row, column=col, rowspan=rowspan, columnspan=colspan, sticky="nesw")def getRandColor(self):return '#' + self.getRandRGB() + self.getRandRGB() + self.getRandRGB()def getRandRGB(self):return '{:02X}'.format(random.randint(0, 255))def draw(self):self.pack()self.pack_propagate(0)self.mainloop()if __name__ == '__main__':App()