zoukankan      html  css  js  c++  java
  • tkinter gui控件回调和grid布局优化

    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:UserspwpluAppDataLocalProgramsPythonPython37python.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:UserspwpluAppDataLocalProgramsPythonPython37python.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

  • 相关阅读:
    asp.net中的Application概述
    Android布局
    Content Provider
    Service
    进程和线程Processes and Threads
    Android模拟器
    Fragment
    Ui Event
    Loader
    sqlite3命令
  • 原文地址:https://www.cnblogs.com/pingwen/p/12642440.html
Copyright © 2011-2022 走看看