2017-05-31 48 views
3

如果mywidget条目发生更改,它应该运行功能atado_enter。如果我在这个函数中加入了一些错误,它会给我提供错误信息,但是如果我想要做某件事,那么它什么都不做。有人能解释我有什么问题吗?没有错误,但不工作,文本更改时运行功能Tkinter

#!usr/bin/python 
#-*- coding: utf-8 -*- 

import os 
import time 
import mysql.connector 
import getpass 
import smtplib 
from email.mime.text import MIMEText 
global atado_kartya_szam 
global atvevo_kartya_szam 
from PIL import Image, ImageTk 
#from Tkinter import Tk, Text, TOP, BOTH, X, N, LEFT 
from Tkinter import * 
from Tkinter import Tk as tk 
from ttk import Frame, Style, Entry, Label 

class Example(Frame): 

    def __init__(self, parent):  
     Frame.__init__(self, parent)   
     self.parent = parent 
     self.initUI() 

    def initUI(self): 
     def atado_enter(*args): 
      print("vmi") 

     self.parent.title("Pozi") 
     self.pack(fill = BOTH, expand=True) 

     frame1 = Frame(self) 
     frame1.pack(fill=X) 

     lbl1 = Label(frame1, text = "ĂtadĂł kártyája", width = 15) 
     lbl1.pack(side = LEFT, padx=5, expand=True) 

     myvar = StringVar() 
     myvar.set('') 
     mywidget = Entry(frame1,textvariable=myvar,width=10) 
     mywidget.pack() 
     myvar.trace('w',atado_enter) 

def main(): 

    root = Tk() 
    root.geometry("550x450+300+300") # width x heigth + x + y (on screen) 
    app = Example(root) 
    root.mainloop() 


if __name__ == '__main__': 
    main() 
+0

我知道你已经有你的答案,但我想提供一种不同的方法。如果你想看看,我已经修改了我的答案。 –

回答

4

一旦initUI完成执行,myvar被垃圾回收,因为有它没有更多的生活引用。获取垃圾收集的StringVar不会触发任何回调。

请尝试保留对该对象的较长寿命的引用。最简单的方法是将其分配给self的属性:

#... rest of function goes here... 
    myvar = StringVar() 
    myvar.set('') 
    mywidget = Entry(frame1,textvariable=myvar,width=10) 
    mywidget.pack() 
    myvar.trace('w',atado_enter) 
    self.myvar = myvar 
+0

你能解释一下我自己做了什么吗? – Daniel

+0

'self'是对由'initUI'初始化的'Example'对象的引用。将myvar分配给它的myvar属性将导致myvar至少在Example对象处于活动状态时一直存在。这足以满足我们的需求;如果Example对象已经死了,那么该窗口对用户不再可见,所以我们不需要'myvar'。 – Kevin

+0

@Kevin我对我的答案做了一些更改,以更符合OP的需求。我意识到你已经正确使用'痕迹'回答了这个问题,所以我想提供一个可能的选择,如果你喜欢看一看。 –

1

首先,我认为你的tkinter导入有问题。

更改此:

from Tkinter import * 
from Tkinter import Tk as tk 
from ttk import Frame, Style, Entry, Label 

要这样:

from Tkinter import * 

看到已经有人使用trace答案,是缺乏我的回答,我决定通过检查过200添加一个有趣的选择毫秒来查看该值是否已经改变。此号码可以更改为任何毫秒。它可能不像追踪那么简单,但它确实有效。

我删除了跟踪并创建了一个函数/方法,它将检查mywidget是否已更改,如果为true,则请致电atado_entry

last_mywidget = [""] 
def CheckMywidget(): 
    if last_mywidget != [mywidget.get()]: 
     atado_enter(mywidget.get()) 
     last_mywidget[0] = mywidget.get() 
     print(last_mywidget) 
     mywidget.after(200, CheckMywidget) 
    else: 
     mywidget.after(200, CheckMywidget) 
CheckMywidget() 

下面是完整的代码:

class Example(Frame): 

    def __init__(self, parent):  
     Frame.__init__(self, parent)   
     self.parent = parent 
     self.initUI() 

    def initUI(self): 
     def atado_enter(*args): 
      print("vmi") 

     self.parent.title("Pozi") 
     self.pack(fill = BOTH, expand=True) 

     frame1 = Frame(self) 
     frame1.pack(fill=X) 

     lbl1 = Label(frame1, text = "ĂtadĂł kártyája", width = 15) 
     lbl1.pack(side = LEFT, padx=5, expand=True) 

     myvar = StringVar() 
     myvar.set('') 
     mywidget = Entry(frame1,textvariable=myvar,width=10) 
     mywidget.pack() 
     #myvar.trace("w", atado_enter) 
     self.myvar = myvar 

     last_mywidget = [""] 
     def CheckMywidget(): 
      if last_mywidget != [mywidget.get()]: 
       atado_enter(mywidget.get()) 
       last_mywidget[0] = mywidget.get() 
       mywidget.after(200, CheckMywidget) 
      else: 
       mywidget.after(200, CheckMywidget) 
     CheckMywidget() 

def main(): 

    root = Tk() 
    root.geometry("550x450+300+300") # width x heigth + x + y (on screen) 
    app = Example(root) 
    root.mainloop() 


if __name__ == '__main__': 
    main() 
+0

我同意进口可能会被清理,但我不认为这是问题的原因。即使实现这些更改,当我在输入框中键入文本时,atado_enter函数也不会执行。 – Kevin

+0

@Kevin我对我的答案做了更新。我想你一旦在输入框中按回车就试图调用一个函数。 –

+0

OP使用可变跟踪,而不是绑定。另外,OP似乎明确地想要使用ttk Entry,而不是Tkinter Entry。 –

相关问题