问题与参考文献
传参问题
在部分函数中会指定调用函数,但其函数参数被指定导致参数无法传递,解决方案:使用匿名函数
匿名函数:lambda
>>> lambda x: (2*x +1 )
at 0x005B33D8>
>>> g = lambda x:(2*x + 1)
>>> g(10)
21
>>> lambda x,y : (x + y)
at 0x0295D420>
>>> g = lambda x,y:(x + y)
>>> g(10,20)
30
正确的在Button的command中传递参数的方法,是使用lambda匿名函数。代码修改成下面这样,实际上只修改了高亮的那一行:
#----------- Copywrite by ESWIN 2020 from guohao@eswin.com -----------#
import Tkinter as tk
def bn_cmd(str=None):
if str is not None:
lb.config(text=str)
root = tk.Tk()
root.geometry('200x100')
lb = tk.Label(root, text='12345')
lb.grid()
tstr = 'I\'m from Button command'
bn = tk.Button(root, text='clickme', command=lambda:bn_cmd(tstr))
bn.grid()
root.mainloop()
这样的写法,就实现了界面初始显示12345,点击clickme按钮后,变成tstr变量的内容,而tstr变量,是通过参数的方式传递近bn_cmd函数的。
这种写法,command指向一个匿名函数,这个匿名函数就是调用bn_cmd函数,并且制定了tstr这个参数。这种方式就实现了Button控件command中传递参数。
Tkinter如何绑定Text内容改变事件
#----------- Copywrite by ESWIN 2020 from guohao@eswin.com -----------#
import Tkinter as tk
root = tk.Tk()
last_text = ''
def text_change(event):
global last_text
got = text.get('1.0', 'end')
if got != last_text:
last_text = got
print('文本被修改了')
text = Text(root)
text.bind('', text_change)
text.grid()
root.mainloop()
参考
Python的GUI编程–Label(标签)
Python2.X和Python3.X文件对话框、下拉列表的不同
今天初次使用Python Tkinter来做了个简单的记事本程序。发现Python2.x和Python3.x的Tkinter模块的好多内置函数都有所改变,这里简单整理一下以备日后查验。
导入方式
Python2.x:
from Tkinter import *
Python3.x:
from tkinter import *
打开文件框
Python2.X:
import tkFileDialog
filename = tkFileDialog.askopenfilename(filetypes=[("bmp格式".decode('gbk'),"bmp")])
注意:Python2.X会有中文乱码问题,需要在"中文"后加.decode(‘gbk’) 。Python3.X则不需要
这里可以加入属性: initialdir 设置默认初始路径。即:
FileName = tkFileDialog.askopenfilename(filetypes=[("bmp格式".decode('gbk'),"bmp")], initialdir = 'E:')
Python3.X:
import tkinter.filedialog
filename=tkinter.filedialog.askopenfilename(filetypes=[("bmp格式","bmp")])
对话框
Python2.X:
import tkFileDialog
showinfo(title='中文标题'.decode('gbk'), message='XXX') #注意:中文要加.decode('gbk')
Python3.X:
import tkinter.messagebox
tkinter.messagebox.showinfo(title='XXX',message='XXX')
下拉列表
Python2.X:
import ttk
注意:如果写from ttk import *会影响Label的属性,这里可能Label会自动调用ttk里的Label?猜测而已
Python3.X:
from tkinter import ttk
用法一样:
myComboList = ['AAA','BBB',]
myCombox = ttk.Combobox(root, values=myComboList )
myCombox .pack()
Tkinter
Python2.7为Tkinter 下列示例均以2.7为主
Python3.7为tkinter
Label & Button 标签和按钮
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
# 实例化object,建立窗口window
window = tk.Tk()
# 给窗口的可视化起名字
window.title('My Window')
# 设定窗口的大小(长 * 宽)
window.geometry('500x300') # 这里的乘是小x
# 在图形界面上设定标签
var = tk.StringVar() # 获取显示变量
# 创建标签
l = tk.Label(window, textvariable=var, bg='green', font=('Arial', 12), width=30, height=2)
# l = tk.Label(window, text='你好!this is Tkinter', bg='green', font=('Arial', 12), width=30, height=2)
# 说明: bg为背景,font为字体,width为长,height为高,这里的长和高是字符的长和高,比如height=2,就是标签有2个字符这么高
# 放置标签
l.pack() # Label内容content区域放置位置,自动调节尺寸
#l.place()
# 放置lable的方法有:1)l.pack(); 2)l.place();
on_hit = False # 控制是否显示的变量
def hit_me(str = None):
global on_hit
if on_hit == False:
on_hit = True
var.set('you hit me')
else:
on_hit = False
var.set("")
# 创建按钮
b = tk.Button(window, text = 'hit me', width = 15, height = 2, command = lambda:hit_me("parameter"))
# 放置按钮
b.pack()
# 主窗口循环显示
window.mainloop()
# 注意,loop因为是循环的意思,window.mainloop就会让window不断的刷新,如果没有mainloop,就是一个静态的window,传入进去的值就不会有循环,mainloop就相当于一个很大的while循环,有个while,每点击一次就会更新一次,所以我们必须要有循环
# 所有的窗口文件都必须有类似的mainloop函数,mainloop是窗口文件的关键的关键。
Entry & Text 输入和文本框
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
# 实例化object,建立窗口window
window = tk.Tk()
# 给窗口的可视化起名字
window.title('My Window')
# 设定窗口的大小(长 * 宽)
window.geometry('500x300') # 这里的乘是小x
# 在图形界面上设定标签
var = tk.StringVar() # 获取显示变量
# 创建标签
l = tk.Label(window, textvariable=var, bg='green', font=('Arial', 12), width=30, height=2)
# l = tk.Label(window, text='你好!this is Tkinter', bg='green', font=('Arial', 12), width=30, height=2)
# 说明: bg为背景,font为字体,width为长,height为高,这里的长和高是字符的长和高,比如height=2,就是标签有2个字符这么高
# 放置标签
l.pack() # Label内容content区域放置位置,自动调节尺寸
#l.place()
# 放置lable的方法有:1)l.pack(); 2)l.place();
def insert_point():
var_data = e.get()
var.set(var_data)
t.insert('insert',var_data)
def insert_end():
var_data = e.get()
var.set(var_data)
t.insert('end',var_data)
# 创建 Entry 窗口
e = tk.Entry(window, show = None)
# show = None时输入的所有字符可显示,当show = "*"时输入的字符均显示为 "*"
e.pack()
# 创建 Text 窗口
t = tk.Text(window, width = 15, height = 2)
t.pack()
# 创建按钮
b1 = tk.Button(window, text = 'insert point', width = 15, height = 2, command = insert_point)
# 放置按钮
b1.pack()
# 创建按钮
b2 = tk.Button(window, text = 'insert end' , width = 15, height = 2, command = insert_end)
# 放置按钮
b2.pack()
# 主窗口循环显示
window.mainloop()
# 所有的窗口文件都必须有类似的mainloop函数,mainloop是窗口文件的关键的关键。
Listbox 列表部件
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
# 实例化object,建立窗口window
window = tk.Tk()
# 给窗口的可视化起名字
window.title('My Window')
# 设定窗口的大小(长 * 宽)
window.geometry('500x300')
var1 = tk.StringVar()
var2 = tk.StringVar()
# 创建标签
l = tk.Label(window, textvariable=var1, bg='green', font=('Arial', 12), width=30, height=2)
l.pack()
# 列表删除
def Delete_List():
getdata = lb.curselection()
if len(getdata) == 0:
return
value = lb.get(getdata)
var1.set(value)
lb.delete(getdata[0])
# 列表追加
def Add_list():
var_data = e.get()
if var_data == "":
var_data = "None"
lb.insert('end', var_data)
var1.set(var_data)
# 创建输入框
e = tk.Entry(window, show = None)
e.pack()
# 创建按钮
b1 = tk.Button(window, text = 'delete list', width = 15, height = 2, command = Delete_List)
b1.pack()
# 创建按钮
b2 = tk.Button(window, text = ' Add list' , width = 15, height = 2, command = Add_list)
b2.pack()
# 创建显示列表
var2.set(('LTE1p4', 'LTE5', 'LTE10', 'LTE15', 'LTE20', 'LTE40'))
# 这里不建议使用列表,使用列表时显示会出问题
lb = tk.Listbox(window, listvariable = var2)
lb.pack()
t = tk.Text(window, width = 15, height = 2)
t.pack()
# 主窗口循环显示
window.mainloop()
# 所有的窗口文件都必须有类似的mainloop函数,mainloop是窗口文件的关键的关键。
Radiobutton 选择按钮
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
# 实例化object,建立窗口window
window = tk.Tk()
# 给窗口的可视化起名字
window.title('My Window')
# 设定窗口的大小(长 * 宽)
window.geometry('500x300')
# 创建标签
l = tk.Label(window, text = "Text can change", bg='green', font=('Arial', 12), width=30, height=2)
l.pack()
var1 = tk.StringVar()
def print_selection():
l.config(text='You have selected ' + var1.get())
r1 = tk.Radiobutton(window, text = 'Option A', variable = var1, value = 'A', command = print_selection)
r1.pack()
r2 = tk.Radiobutton(window, text = 'Option B', variable = var1, value = 'B', command = print_selection)
r2.pack()
r3 = tk.Radiobutton(window, text = 'Option C', variable = var1, value = 'C', command = print_selection)
r3.pack()
window.mainloop()
Scale 尺度
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
# 实例化object,建立窗口window
window = tk.Tk()
# 给窗口的可视化起名字
window.title('My Window')
# 设定窗口的大小(长 * 宽)
window.geometry('500x300')
# 创建标签
l = tk.Label(window, text = "Text can change", bg='green', font=('Arial', 12), width=30, height=2)
l.pack()
def print_selection(V):
l.config(text='You have selected ' + V)
s = tk.Scale(window, label = 'tty me', from_ = 5, to = 10, orient = tk.HORIZONTAL, length = 200, showvalue = 1, \
tickinterval = 1, resolution = 0.01, command = print_selection)
# label:名字,from_:起始,to:结束数值,orient:方向(HORIZONTAL【横向】),lenght:像素宽度,showvalue:显示当前选择的数值,
#tickinterval:标签的单位长度。resolution变量的精度
s.pack()
window.mainloop()
Checkbutton 勾选项
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
# 实例化object,建立窗口window
window = tk.Tk()
# 给窗口的可视化起名字
window.title('My Window')
# 设定窗口的大小(长 * 宽)
window.geometry('500x300')
# 创建标签
l = tk.Label(window, text = "Text can change", bg='green', font=('Arial', 12), width=30, height=2)
l.pack()
def print_selection():
l.config(text='You have selected ' + var1.get() + " " + var2.get())
# dir(Tkinter)
var1 = tk.StringVar()
var2 = tk.StringVar()
c1 = tk.Checkbutton(window, text = 'C', variable = var1, onvalue = 'C', offvalue = "", command = print_selection)
# variable:该勾选项指定的变量,onvalue:勾上时的赋值,offvalue:未勾上时的赋值,command:动作时触发的函数
c2 = tk.Checkbutton(window, text = 'Python', variable = var2, onvalue = 'Python', offvalue = "", command = print_selection)
c1.pack()
c2.pack()
window.mainloop()
Canvas 画布
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
# 实例化object,建立窗口window
window = tk.Tk()
# 给窗口的可视化起名字
window.title('My Window')
# 设定窗口的大小(长 * 宽)
window.geometry('500x500')
# 创建标签
l = tk.Label(window, text = "Text can change", bg='green', font=('Arial', 12), width=30, height=2)
l.pack()
canvas = tk.Canvas(window, bg = 'blue', height = 180, width = 180)
# bg:背景颜色,height:指定高度,width:指定宽度
image_file = tk.PhotoImage(file = 'bbb.gif')
# file:指定图片文件
image = canvas.create_image(-27, 0, anchor = 'nw', image = image_file)
# 参数1,2为锚的位置,anchor:指定图片的锚(小写)
#(上[n]、下[s]、左[w]、右[e]、左上[nw]、右上[ne]、左下[sw]、右下[se]、中间[center])
line1 = canvas.create_line(0, 0, 180, 180, fill = 'red')
# 画线
line2 = canvas.create_line(0, 180, 180, 0)
oval = canvas.create_oval(0, 0, 180, 180)#, fill= 'red'
# 画圆
arc1 = canvas.create_arc (-18,-18, 142, 142, start = -45, extent = 90, fill = 'green')
# 画扇形
arc2 = canvas.create_arc (38, 38, 198, 198, start = 135, extent = 90, fill = 'blue')
rect = canvas.create_rectangle(5, 5, 175, 175)
# 画矩形
canvas.pack()
VoorMove = 0
def moveit1():
global VoorMove
VoorMove += 1
l.config(text='Voordinate Move %d'%VoorMove)
canvas.move(arc1, 1, 1)
canvas.move(arc2,-1,-1)
def moveit2():
global VoorMove
VoorMove -= 1
l.config(text='Voordinate Move %d'%VoorMove)
canvas.move(arc1,-1,-1)
canvas.move(arc2, 1, 1)
b = tk.Button(window, text = 'move + ', command = moveit1).pack()
b = tk.Button(window, text = 'move - ', command = moveit2).pack()
window.mainloop()
Menubar 菜单
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
# 实例化object,建立窗口window
window = tk.Tk()
# 给窗口的可视化起名字
window.title('My Window')
# 设定窗口的大小(长 * 宽)
window.geometry('500x500')
# 创建标签
l = tk.Label(window, text = "Text can change", bg='green', font=('Arial', 12), width=30, height=2)
l.pack()
counter = 0
def do_job():
global counter
l.config(text = ("counter = %d"%counter))
counter += 1
menubar = tk.Menu(window)
# 创建主菜单
filemenu = tk.Menu(menubar, tearoff = 0)
# 在主菜单下创建第一页的菜单
editmenu = tk.Menu(menubar, tearoff = 0)
# 在主菜单下创建第二页的菜单
submenu = tk.Menu(editmenu, tearoff = 0)
# 在第二页菜单下加入子菜单
menubar.add_cascade (label = 'File', menu = filemenu)
# 将第一页菜单链接到主菜单、设定第一页菜单在主菜单中的名字
menubar.add_cascade (label = 'Edit', menu = editmenu)
# 将第二页菜单链接到主菜单、设定第二页菜单在主菜单中的名字
menubar.add_cascade (label = 'Add', command = do_job)
filemenu.add_cascade(label = 'New', command = do_job) # 设置菜单内选项
filemenu.add_cascade(label = 'Open', command = do_job) # 设置菜单内选项
filemenu.add_cascade(label = 'Save', command = do_job) # 设置菜单内选项
filemenu.add_separator() # 在菜单内创建分割线
filemenu.add_cascade(label = 'Exit', command = window.quit)# window.quit:退出函数
editmenu.add_cascade(label = 'Cut', command = do_job) # 设置菜单内选项
editmenu.add_cascade(label = 'Copy', command = do_job) # 设置菜单内选项
editmenu.add_cascade(label = 'Paste', command = do_job) # 设置菜单内选项
editmenu.add_cascade(label = 'Submenu', menu = submenu) # 设置菜单内选项 , underline = 0
submenu.add_cascade (label = 'submenu_1', command = do_job)
submenu.add_cascade (label = 'submenu_2', command = do_job)
submenu.add_cascade (label = 'submenu_3', command = do_job)
window.config(menu = menubar)
window.mainloop()
Frame 框架
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
# 实例化object,建立窗口window
window = tk.Tk()
# 给窗口的可视化起名字
window.title('My Window')
# 设定窗口的大小(长 * 宽)
window.geometry('500x500')
# 创建标签
l = tk.Label(window, text = "Text can change", bg='green', font=('Arial', 12), width=30, height=2)
l.pack()
tk.Label(window, text = " window1 ", bg='green', font=('Arial', 12), width=30, height=2).pack()
frm = tk.Frame(window)
frm.pack()
# 创建框架 frm 位置在 window1 之下
tk.Label(window, text = " window2 ", bg='green', font=('Arial', 12), width=30, height=2).pack()
frm_R = tk.Frame(frm)
frm_R.pack(side = 'right')
# 在 frm 框架内创建框架 【frm_R会覆盖frm,若在window下则不会覆盖】
# 将创建好的 frm_R 加载在 frm 的右半部分
frm_L = tk.Frame(frm)
frm_L.pack(side = 'left')
# 在 frm 框架内创建框架 【frm_L会覆盖frm,若在window下则不会覆盖】
# 将创建好的 frm_L 加载在 frm 的左半部分,因在 frm_R 后挂在,故此 frm_L 会被 frm_R 覆盖
tk.Label(frm , text = " frm " , bg='green', font=('Arial', 12), width=30, height=2).pack()
tk.Label(frm_L , text = " frm_L " , bg='green', font=('Arial', 12), width=30, height=2).pack()
tk.Label(frm_R , text = " frm_R " , bg='green', font=('Arial', 12), width=30, height=2).pack()
window.mainloop()
ttk
Python2.7为ttk
Python3.7为tkinter.ttk
Combobox 下拉选项
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter大连做人流多少钱 http://mobile.bhbyby.net/
import ttk # 导入ttk模块,因为下拉菜单控件在ttk中
wuya = Tkinter.Tk()
wuya.title("wuya")
wuya.geometry("300x200+10+20")
# 创建下拉菜单
cmb = ttk.Combobox(wuya)
cmb.pack()
# 设置下拉菜单中的值
cmb['value'] = ('上海','北京','天津','广州')
# 设置默认值,即默认下拉框中的内容
cmb.current(2)
# 默认值中的内容为索引,从0开始
# 执行函数
def func(event):
text.insert('insert',cmb.get()+"\n")
cmb.bind("<>",func)
text = Tkinter.Text(wuya)
text.pack()
wuya.mainloop()
测试代码
tkinter 调整 label 背景颜色的测试
#----------- Copywrite by GuoHowe from luckgh@Outlook.com -----------#
import Tkinter as tk # 使用Tkinter前需要先导入
GRBW = dict()
GRBW['rgb'] = "#BCFFFF" # 用于更改颜色
GRBW['r'] = 100
GRBW['g'] = 100
GRBW['b'] = 100
GRBW['w'] = 100
window = tk.Tk() # 实例化一个窗口
window.title('Color setting') # 定义窗口标题
window.geometry('400x600') # 定义窗口大小
l = tk.Label(window, bg='yellow', width=200, height=2, text='empty')
l.pack()
global GRBW
#=========================== 对Text控件进行操作 ================================#
def cut(text, event=None):
text.event_generate("<>")
def copy(text, event=None):
text.get('sel.first', 'sel.last')
text.event_generate("<>")
def paste(text, event=None):
text.event_generate('<>')
def fresh(text, t):
text.delete(1.0, tk.END)
text.insert(tk.INSERT, t)
def show(text):
T1 = text.get(0.0, tk.END)
return T1
def select_all(text, event=None):
text.tag_add(tk.SEL, "1.0", tk.END)
text.mark_set(tk.INSERT, "1.0")
text.see(tk.INSERT)
copy(text)
return 'break'
#============================ 构建颜色计算函数 =================================#
def print_selection():
global GRBW
r = GRBW['r']
g = GRBW['g']
b = GRBW['b']
w = GRBW['w']
#转化16进制并格式化
rv = hex(int(255.0 * (float(GRBW['r']) * float(w) / 10000.0)))#0x xx 不合适
srv = '%02x' % int(255.0 * (float(r) * float(w) / 10000.0))
sgv = '%02x' % int(255.0 * (float(g) * float(w) / 10000.0))
sbv = '%02x' % int(255.0 * (float(b) * float(w) / 10000.0))
#print(srv)
GRBW['rgb']="#"+srv+sgv+sbv
l.configure(bg=GRBW['rgb'])
l.config(text='R:' + str(r) + '%,G:' + str(g) + '%,B:' + str(b) + '%,W:' + str(w)+"% C:"+GRBW['rgb'])
jsonstr1=("\"color\":{\"r\":%1.2f,\"g\":%1.2f,\"b\":%1.2f,\"w\":%1.2f}"
%(float(r)/100.0, float(g)/100.0, float(b)/100.0, float(w)/100.0))
jsonstr2=("bg = %s"%GRBW['rgb'])
fresh(text1, jsonstr1+'\r\n'+jsonstr2)
#============================= 构建尺度函数 ===================================#
def setRGB(v, RgbLog):
global GRBW
GRBW[RgbLog]=v
print_selection()
#=============================== 创建尺度 =====================================#
rs = tk.Scale(window, label='R:', from_=0, to=100, orient=tk.HORIZONTAL, length=200, showvalue=1, tickinterval=25,
resolution=1, command=lambda v:setRGB(v, 'r'))
rs.pack() # 显示名字 从5-11 条方向 长度(像素),是否直接显示值,标签的单位长度,保留精度 ,定义功能
rs.set(GRBW['r'])
gs = tk.Scale(window, label='G:', from_=0, to=100, orient=tk.HORIZONTAL, length=200, showvalue=1, tickinterval=25,
resolution=1, command=lambda v:setRGB(v, 'g'))
gs.pack()
gs.set(GRBW['g'])
bs = tk.Scale(window, label='B:', from_=0, to=100, orient=tk.HORIZONTAL, length=200, showvalue=1, tickinterval=25,
resolution=1, command=lambda v:setRGB(v, 'b'))
bs.pack()
bs.set(GRBW['b'])
ws = tk.Scale(window, label='W:', from_=0, to=100, orient=tk.HORIZONTAL, length=200, showvalue=1, tickinterval=25,
resolution=1, command=lambda v:setRGB(v, 'w'))
ws.pack()
ws.set(GRBW['w'])
#============================== 创建文本框 ====================================#
text1 = tk.Text(window,width=30,height=5)
text1.pack()
text1.insert(tk.INSERT,'I love you')
#=============================== 创建按钮 =====================================#
# Select all the text in textbox
button = tk.Button(window,text="SelectAndCopy",command = lambda:select_all(text1))
button.pack()
text1.focus_set()
#======================================================================================#
#button.pack(fill=tk.BOTH, expand=1)
#text1.window_create(tk.INSERT,window=button)