PYTHON的tkinter类编码技巧

1 添加用户回调函数
1.1 三种回调处理器
1.1.2 lambda 回调处理器

#lambda 基础说明 -->  lambda argument:expression
te = lambda c:print(c)  # lambda 返回的是一个可运行的函数对象

# 等价于
def te(c):
    print(c)

# 处理器,上述例子中,print(c)这个函数被称为处理器
对于GUI的效果:处理器的回调被延迟,可以添加需要的参数。

1.1.2 Bound方法的回调处理器(绑定方法self)
在类中绑定方法。如下所示

class HelloClass:
    def __init__(self):
        widget = Button(None, test = 'Hello event world', command = self.quit)
        widget.pack()
        
    def quit(self):
        print('Hello class method world')
        sys.exit()
        
# 实际上传送的参数时 self 和 quit, 如果

这里要特别说明一点,传入一个未绑定的方法在GUI中是不起作用的。

1.1.3 可调用类对象的回调处理器
在可调用类的绑定方法,主要是通过 call 方法来实现拦截运行。例子如下:

import sys
from tkinter import *

class HelloCallable:
    
    def __init__(self):
        self.msg = 'Hello __call__ world'
        
    def __call__(self):
        print(self.msg)
        sys.exit()

经过试验,单独的调用HelloCallable,函数 call 里面的函数不会运行。

扩展1:试验,该种方法,在pyqt是是否可以使用;结论:可用,示例如下:

from PyQt5.QtWidgets import QPushButton,QApplication,QWidget
import sys

class test_call:
    def __init__(self):
        self.msg = 'test'

    def __call__(self):
        print(self.msg)


app=QApplication(sys.argv)
w = QWidget()
b = QPushButton(w, text = 'test')
b.clicked.connect(test_call())
w.show()

sys.exit(app.exec_())

扩展2:__call__的本质,实际上是可对对象进行调用,通过"()"符号

2 用类实现组件的自定义设置
1.通过继承的方式,实现自己的定制组件,子类继承超类。

from tkinter import *

class HelloButton(Button):
    def __init__(self, parent = None, **config):
        Button.__init__(self, parent, **config)
        self.pack()
        self.config(command=self.callback)
        
    def callback(self):
        print("Goodbye world...")
        self.quit()

2.用类复用GUI部件 | 添加类部件 | 扩展类部件

大型GUI界面通常作为Frame的子类,用回调处理器作为方法。这种结构,提供了存储事件间信息的天然位置:用实例属性来记录状态。

Frame的子类都是组件,可以通过指定真实的父组件,实现整个组件包依赖于其他某个东西!(这个很重要)
from tkinter import *

# 这是一个依托于Frame实现的一个按钮
class Hello(Frame):
    def __init__(self, parent=None):
        Frame.__init__(self, parent)
        self.pack()
        self.data = 1
        self.make_widgets()
        
    def make_widgets(self):
        widget = Button(self, text='Hello frame world!', command = self.message)
        widget.pack(side = LEFT)
        
    def message(self):
        self.data += 1
        print('Hello frame world %s!' % self.data)
        
# 把上面的按钮放到另外一个框架中
parent = Frame(None)
parent.pack()
Hello(parent).pack(side=RIGHT)                                     # 把 Hello 作为 parent 的子组件,打包在右侧
Button(parent, text='Attach', command=exit).pack(side=LEFT)        # 在左边增加一个按钮
parent.mainloop()
  扩展类部件,主要是通过继承并重写类的方法。

3.独立的容器类

 通过创建独立容器,来获取前面所提到的所有基于类部件的好处。

  优点:可以避免代码命名冲突

             类可以通过定义方法,将获取的不明属性引导至内嵌的Frame
from tkinter import *

class HelloPackage:
    
    def __init__(self, parent=None):
        self.top = Frame(parent)
        self.top.pack()
        self.data = 0
        self.make_widgets()
        
    def make_widgets(self):
        Button(self.top, text = 'Bye', command = self.top.quit).pack(side=LEFT)
        Button(self.top, text = 'Hye', command = self.message).pack(RIGHT)
        
    def message(self):
        self.data += 1
        print('Hello number', self.data)
        
# 通过 __getattr__ 将获取的不明属性 引导至 内嵌的Frame

class HellPackage2(HelloPackage):
    
    def __getattr__(self, name):
        return getattr(self.top, name)
        
# 运行, mainloop()需要对一个组件,这里需要方为到top才是一个Frame
if __name__ == '__main__':HelloPackage().top.mainloop() 

3 额外话题 getattr_
这部分问题,可能讨论的不全面,仅为个人的认知。例子说明。

# 属性访问
class test:
    
    def __init__(self):
        self.a = 1
        self.b = 1
    
    def callback(self, name):
        print('get name:{}'.format(name))
        
    def __getattr__(self, name):
        print('input name:{}'.format(name))  # 打印传入的变量
        return self.callback
        
# 组合类————组合优于继承,引用于 https://www.cnblogs.com/xybaby/p/6280313.html
class adaptee(object):
    def foo(self):
        print 'foo in adaptee'
    def bar(self):
        print 'bar in adaptee'

class adapter(object):
    def __init__(self):
        self.adaptee = adaptee()

    def foo(self):
        print 'foo in adapter'
        self.adaptee.foo()

    def __getattr__(self, name):
        return getattr(self.adaptee, name)

if __name__ == '__main__':
    a = adapter()
    a.foo()
    a.bar()

# 在类adapter中就能访问adaptee的属性方法 通过 “.”的形式
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值