python tkinter textvariable_python – tkinter.Text:将变量绑定到窗口小部件文本内容

如果您愿意危险地生活,可以挂钩文本小部件的内部,并在内容发生变化时让它调用函数,无论它如何变化.

诀窍是用代理替换底层的tk widget命令.此代理负责执行真正的文本小部件所做的任何操作,然后发送虚拟事件,如果它执行的操作是插入或删除文本.

有了这个,只需要设置一个绑定到该事件,并在变量上放置一个读取跟踪.当然,如果您尝试在文本中插入小部件或图像,它们将不会反映在textvariable中.

这是一个快速而肮脏的例子,没有任何真实的测试.这使用了我用来在文本小部件中实现行号的相同技术(参见https://stackoverflow.com/a/16375233)

import Tkinter as tk

import random

import timeit

class TextWithVar(tk.Text):

'''A text widget that accepts a 'textvariable' option'''

def __init__(self, parent, *args, **kwargs):

try:

self._textvariable = kwargs.pop("textvariable")

except KeyError:

self._textvariable = None

tk.Text.__init__(self, parent, *args, **kwargs)

# if the variable has data in it, use it to initialize

# the widget

if self._textvariable is not None:

self.insert("1.0", self._textvariable.get())

# this defines an internal proxy which generates a

# virtual event whenever text is inserted or deleted

self.tk.eval('''

proc widget_proxy {widget widget_command args} {

# call the real tk widget command with the real args

set result [uplevel [linsert $args 0 $widget_command]]

# if the contents changed, generate an event we can bind to

if {([lindex $args 0] in {insert replace delete})} {

event generate $widget <> -when tail

}

# return the result from the real widget command

return $result

}

''')

# this replaces the underlying widget with the proxy

self.tk.eval('''

rename {widget} _{widget}

interp alias {{}} ::{widget} {{}} widget_proxy {widget} _{widget}

'''.format(widget=str(self)))

# set up a binding to update the variable whenever

# the widget changes

self.bind("<>", self._on_widget_change)

# set up a trace to update the text widget when the

# variable changes

if self._textvariable is not None:

self._textvariable.trace("wu", self._on_var_change)

def _on_var_change(self, *args):

'''Change the text widget when the associated textvariable changes'''

# only change the widget if something actually

# changed, otherwise we'll get into an endless

# loop

text_current = self.get("1.0", "end-1c")

var_current = self._textvariable.get()

if text_current != var_current:

self.delete("1.0", "end")

self.insert("1.0", var_current)

def _on_widget_change(self, event=None):

'''Change the variable when the widget changes'''

if self._textvariable is not None:

self._textvariable.set(self.get("1.0", "end-1c"))

class Example(tk.Frame):

def __init__(self, parent):

tk.Frame.__init__(self, parent)

self.textvar = tk.StringVar()

self.textvar.set("Hello, world!")

# create an entry widget and a text widget that

# share a textvariable; typing in one should update

# the other

self.entry = tk.Entry(self, textvariable=self.textvar)

self.text = TextWithVar(self,textvariable=self.textvar,

borderwidth=1, relief="sunken",

background="bisque")

self.entry.pack(side="top", fill="x", expand=True)

self.text.pack(side="top",fill="both", expand=True)

if __name__ == "__main__":

root = tk.Tk()

Example(root).pack(fill="both", expand=True)

root.mainloop()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值