0, 引子
Tkinter 是 Python 的标准 GUI 库. Python 使用 Tkinter 可以快速的创建 GUI 应用程序. 由于 Tkinter 是内置到 python 的安装包中, 只要安装好 Python 之后就能 import Tkinter 库, 非常方便.
1, 控件回调
1.1 按钮回调
- import tkinter as tk
- def printInfo():
- print("printInfo button click")
- myWindow = tk.Tk()
- myWindow.geometry('300x200')
- myWindow.title('Python GUI Learning')
- myWindow.resizable(width=False, height=False)
- #Quit 按钮退出; Run 按钮打印计算结果
- tk.Button(myWindow, text='Quit', command=myWindow.quit).grid(row=2, column=0, padx=5, pady=5)
- tk.Button(myWindow, text='Run', command=printInfo).grid(row=2, column=1, padx=5, pady=5)
- myWindow.mainloop()
按下 Run 打印信息, 按下 Quit 退出.
- C:\Users\pwplu\AppData\Local\Programs\Python\Python37\python.exe E:/test1/test_opencv/test3.py
- printInfo button click
- printInfo button click
1.2 单选框回调
- r = tk.IntVar()
- def radCall():
- print(f"radio:{r.get()}")
- radio1=tk.Radiobutton(myWindow, text="one",value=1,variable=r,command=radCall).grid()
- radio2=tk.Radiobutton(myWindow, text="two",value=2,variable=r,command=radCall).grid()
选择单选框后, 触发回调输出:
- C:\Users\pwplu\AppData\Local\Programs\Python\Python37\python.exe E:/test1/test_opencv/test3.py
- radio:1
- radio:1
- radio:1
- radio:2
- radio:2
如果希望重复点击同个单选框时不打印相同的内容, 即只有值变化时候才触发回调则需要修改回调函数, 记录当前的值即可:
- prv = tk.IntVar()
- r = tk.IntVar()
- prv = -1
- def radCall():
- global prv
- radSel = r.get()
- if radSel == 1 and prv != radSel:
- print(r.get())
- elif radSel == 2 and prv != radSel:
- print(r.get())
- prv = radSel
1.3 滑动条回调与只在释放时候触发一次
- def scaleFunc(v):
- print(f"radio:{v}")
- scale1 = tk.Scale( myWindow, from_=1, to=100, length=100, orient=tk.HORIZONTAL, command = scaleFunc)
- scale1.pack()
- scale1.set(15)
- scale2 = tk.Scale( myWindow, from_=1, to=100, length=150, orient=tk.VERTICAL, command = scaleFunc)
- scale2.pack()
- scale2.set(10)
当滑动条滑动时, 会一直触发回调函数, 并且 scaleFunc 无法区分是哪一个滑动条动作触发的动作.
一般地, 希望不要反复触发回调函数, 而是释放时触发一次即可, 并不需要中间的过程, 以减少资源消耗. 那么可以捕捉鼠标的操作, 滑动条 command 参数无法完成这个功能, 可以为滑动条绑定鼠标事件, 鼠标松开时触发一次.
- def scaleFunc(event):
- print(f"radio:{event}, value={var1.get()}")
- var1 = tk.IntVar()
- scale1 = tk.Scale( myWindow, variable = var1, from_=1, to=100, length=100, orient=tk.HORIZONTAL)
- scale1.pack()
- scale1.set(15)
- scale1.bind("<ButtonRelease-1>", scaleFunc)
输出如下, 调为 1, 改到 85, 再调到 51, 只触发了 3 次.
- radio:<ButtonRelease event state=Mod1|Button1 num=1 x=5 y=31>, value=1
- radio:<ButtonRelease event state=Mod1|Button1 num=1 x=74 y=30>, value=85
- radio:<ButtonRelease event state=Mod1|Button1 num=1 x=47 y=33>, value=51
2,grid 布局
在一个小工具项目中, 出现了界面布局的问题, grid 按照行列对齐方式布局.
因为不同的元素尺寸不同, 导致下面的单色选项的 R-G-B 二级选项, 单选框无法对齐. 第 6 行 RGB 分别对齐 1,2,3 列, 但是低二列和第三列跑到最右侧, 第一列需要对齐图像中心, 那么第二列就会出现的图像空间的右侧, 无法挨着红色单选框连续排列.
- radio5r=tk.Radiobutton(myWindow, text="红色", value=51, variable=r, command=radCall5r)
- radio5g=tk.Radiobutton(myWindow, text="绿色", value=52, variable=r, command=radCall5g)
- radio5b=tk.Radiobutton(myWindow, text="蓝色", value=53, variable=r, command=radCall5b)
- radio5r.grid(row=6, column=1, sticky=tk.W, ipadx = 15)
- radio5g.grid(row=6, column=2, sticky=tk.W, ipadx = 15)
- radio5b.grid(row=6, column=3, sticky=tk.W, ipadx = 15)
这个问题怎么解决? 可以添加一个 frame 空间, 把 R-G-B 二级单选框当做一个整体处理, frame 排列在第一列即可.
- group = tk.LabelFrame(myWindow, text="R-G-B")
- group.grid(row=6, column=1, sticky=tk.W, ipadx = 5)
- radio5r=tk.Radiobutton(group, text="红色", value=51, variable=r, command=radCall5r)
- radio5g=tk.Radiobutton(group, text="绿色", value=52, variable=r, command=radCall5g)
- radio5b=tk.Radiobutton(group, text="蓝色", value=53, variable=r, command=radCall5b)
另外若去除 R-G-B 二级组合的 Frame 的外框, 则就实现了三个单选框按顺序紧凑排列的效果.
- group = tk.LabelFrame(myWindow, borderwidth =0) #边框为 0 就看不到边框了
- group.grid(row=6, column=1, sticky=tk.W, ipadx = 5)
3, 附录
1)Tkinter 组件
2)Grid 结构管理器的参数
4, 参考文档
1,Python-- 交互式图形编程
- https://www.cnblogs.com/ruo-li-suo-yi/p/7420738.html
- 2,Python Tkinter grid() Method
- https://www.tutorialspoint.com/python3/tk_grid.htm
来源: https://www.cnblogs.com/pingwen/p/12642440.html