No error but not working, run function on Tkinter text change

If the entry in mywidget changes, it should run the function atado_enter

. If I put some error in this function it will give me an msg error, but if I want to do something, it strictly does nothing. Can someone explain to me what is wrong with it?

#!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()  

      

+3


source to share


2 answers


As soon as initUI

execution completes, it myvar

gets garbage because there are no more references to it. StringVar, which is garbage collected, does not call any callbacks.

Try to keep a longer object reference. The easiest way to do this is to assign an attribute to it 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

      

+4


source


Firstly. I think you have a problem with your tkinter imports.

Change this:

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

      

For this:

from Tkinter import *

      



Seeing that there was already an answer using using trace

and my answer was missing, I decided to add an interesting alternative by checking in 200 milliseconds to see if the value changed. This number can be changed to any ms value. It may not be as easy as tracing, but it works.

I removed the trace and created a function / method that will check if it has changed mywidget

and if true then call 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()

      

Here's the complete code:

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()  

      

+1


source







All Articles