1

I'm trying to see whether or not a value entered in the Entry widget is stored inside the StringVar() object but when I print the length of the string value object, it says 0.

class POS(tk.Tk):
def __init__(self,*args,**kwargs):
    tk.Tk.__init__(self, *args, **kwargs)
    """
    some code to build multiple frames here
    """

class MainPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)

        frame5 = Frame(self, bg = "pink")
        frame5.pack(fill = BOTH)

        frame5Label1 = tk.Label(frame5, text = "Product Bar Code", font = NORMAL_FONT)
        frame5Label1.grid(row = 0, column = 0, padx=5, pady=5, sticky = W)

        barCode = StringVar()
        frame5EntryBox = ttk.Entry(frame5, textvariable = barCode, width = 40)
        frame5EntryBox.grid(row = 0, column = 1, padx = 5, pady = 5)

        frame5Button = ttk.Button(frame5, text = "Add Item", command = lambda: updateCustomerList(barCode))
        frame5Button.grid(row = 0, column = 2, padx = 130, pady = 10)


def updateCustomerList(barCode):
    print(len(barCode.get()))

app = POS()
app.geometry("700x700")
app.resizable(False,False)
app.mainloop()
6
  • 1
    You're calling the print statement about 1 millisecond after you create the widget, and since you haven't given it a value, the value is the empty string. Commented Jan 7, 2018 at 20:50
  • 1
    Please create a minimal reproducible example. Commented Jan 7, 2018 at 20:56
  • How would I make it work with the button press? I did the same thing with the button press where I'd output the same print statement. I could add a sleep variable but if the user takes too long then it wouldn't work as well. Is there a wait to run that would work with these widgets? Commented Jan 7, 2018 at 20:56
  • Define a proper function to be used as button callback, call that print inside that function. Commented Jan 7, 2018 at 21:23
  • mainloop() starts program so your len() is executed even before tkinter displays window and when frame5EntryBox and barCode are still empty. Assign to button normal function with print(len(barCode.get())). And don't forget to put some text in frame5EntryBox before you press button. Commented Jan 7, 2018 at 21:28

1 Answer 1

1

Minimal working example which displays length of StringVar assigned to Entry after pressing Button

import tkinter as tk

# --- functions ---

def check():
    print('len:', len(var.get()))

# --- main ---

root = tk.Tk()

var = tk.StringVar()

ent = tk.Entry(root, textvariable=var)
ent.pack()

but = tk.Button(root, text="Check", command=check)
but.pack()

root.mainloop()

mainloop displays window with widgets so using len() before starting mainloop makes no sense because var is still empty.


EDIT: with your class and function outside class

import tkinter as tk
from tkinter import ttk

# --- classes ---

class MainPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        frame5 = tk.Frame(self, bg="pink")
        frame5.pack(fill="both")

        frame5Label1 = tk.Label(frame5, text="Product Bar Code", font="NORMAL_FONT")
        frame5Label1.grid(row=0, column=0, padx=5, pady=5, sticky="w")

        barCode = tk.StringVar()
        frame5EntryBox = ttk.Entry(frame5, textvariable=barCode, width=40)
        frame5EntryBox.grid(row=0, column=1, padx=5, pady=5)

        frame5Button = ttk.Button(frame5, text="Add Item", command=lambda:updateCustomerList(barCode))
        frame5Button.grid(row=0, column=2, padx=130, pady=10)

# --- functions ---

def updateCustomerList(barCode):
    print(len(barCode.get()))

# --- main ---

root = tk.Tk()

main = MainPage(root, root)
main.pack()

root.mainloop()

Or using self. and putting function inside class as method

import tkinter as tk
from tkinter import ttk

# --- classes ---

class MainPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        frame5 = tk.Frame(self, bg="pink")
        frame5.pack(fill="both")

        frame5Label1 = tk.Label(frame5, text="Product Bar Code", font="NORMAL_FONT")
        frame5Label1.grid(row=0, column=0, padx=5, pady=5, sticky="w")

        self.barCode = tk.StringVar()
        frame5EntryBox = ttk.Entry(frame5, textvariable=self.barCode, width=40)
        frame5EntryBox.grid(row=0, column=1, padx=5, pady=5)

        frame5Button = ttk.Button(frame5, text="Add Item", command=self.updateCustomerList)
        frame5Button.grid(row=0, column=2, padx=130, pady=10)

    def updateCustomerList(self):
        print(len(self.barCode.get()))

# --- functions ---


# --- main ---

root = tk.Tk()

main = MainPage(root, root)
main.pack()

root.mainloop()
Sign up to request clarification or add additional context in comments.

11 Comments

I've been trying to replicate this into my code but since i've built multiple frames within the app, it gets confusing on where to put your "check" function. As of the current edited code I have up, I still have the same problem. I've tried to put the function before and after the init MainFramePage function but it says that the function is not defined.
I would put this inside MainFramePage as its method and I whould use self.barCode so I could use it without lambda.
if you have error "function is not defined" then maybe you have wrong indentions and function is inside class but it has to be outside class.
I've tried the first one on your edit before and I still got a value of 0 (i.e. empty) and I've tried out using self and has the same answer: 0 (i.e. empty)
did you put text in Entry before you press button ? Or show full code - it can be link to external drive or GitHub or similar.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.