2017-05-31 32 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。 –

相關問題