Michael Norman
Michael Norman

Reputation: 547

Printing variables in tkinter GUI

This is my code:

import pandas as pd

from tkinter import *

master = Tk()

label1= Label(master, text='Department')
label1.grid(row=0, column=0)

textBox = Text(master, height=1, width=10)
textBox.grid(row=0, column=1)

def retrieve_input():
    Department = textBox.get("1.0","end-1c") 

    fileread = pd.read_csv('50.csv', encoding='latin-1')
    filevalue = fileread.loc[fileread['Customer'].str.contains(Department, na=False)]    



    def printSomething():
        label = Label(master, textvariable=filevalue)
        label.grid(row=3, column=1) 



button1 = Button(master,text="Show Values", command=lambda: retrieve_input())
button1.grid(row=2, column=1)

mainloop( )

I have searched around Stack Overflow of how to do this, and was able to construct my code up until this point, However when I click the Show values button, nothing happens. I could find nowhere online that helped address this issue. Is there something fundamentally wrong with my code? Using Python 3.7

Upvotes: 1

Views: 2775

Answers (2)

lmiguelvargasf
lmiguelvargasf

Reputation: 69735

Considering you are running Python 3.7, as you said, the following code will solve your problem:

import pandas as pd

from tkinter import *

master = Tk()

label1= Label(master, text='Department')
label1.grid(row=0, column=0)

textBox = Text(master, height=1, width=10)
textBox.grid(row=0, column=1)

def retrieve_input():
    global text
    department = textBox.get("1.0","end-1c")
    fileread = pd.read_csv('50.csv', encoding='latin-1')

    filevalue = fileread.loc[fileread['Customer'].str.contains("Lam Dep", na=False)]

    text.set(filevalue)


button1 = Button(master,text="Show Values", command=retrieve_input)
button1.grid(row=2, column=1)
text = StringVar()
label = Label(master, textvariable=text)
label.grid(row=0, column=1)


mainloop()

You are facing these problems:

  1. You are defining an inner function printSomething which is never called.

  2. Even if you were calling printSomething you are going to create a new Label every time you press button1.

  3. In this as, you don't need to use lambda to pass the callback that will be executed, you can simply pass command=retrieve_input

The simplest solution might be to define a StringVar (text) which is going to be associated with a Label (label), and when you press the button button1 you update call the method set on that variable text.

Upvotes: 1

abarnert
abarnert

Reputation: 365657

You define a nested printSomething function that would display something, but you never call that function.

This would fix that problem:

def retrieve_input():
    Department = textBox.get("1.0","end-1c") 

    fileread = pd.read_csv('50.csv', encoding='latin-1')
    filevalue = fileread.loc[fileread['Customer'].str.contains("Lam Dep", na=False)]    

    def printSomething():
        label = Label(master, textvariable=filevalue)
        label.grid(row=3, column=1) 

    printSomething()

But I'm not sure why you need the function in the first place; you can just do this:

def retrieve_input():
    Department = textBox.get("1.0","end-1c") 

    fileread = pd.read_csv('50.csv', encoding='latin-1')
    filevalue = fileread.loc[fileread['Customer'].str.contains("Lam Dep", na=False)]    

    label = Label(master, textvariable=filevalue)
    label.grid(row=3, column=1) 

But you have a second problem: You're trying to set the textvariable=filevalue, but that doesn't make any sense.

The textvariable has to be a tkinter.StringVar instance, not a plain old Python string. You can then set the StringVar to hold your string.

    filevar = StringVar()
    filevar.set(filevalue)
    label = Label(master, textvariable=filevar)
    label.grid(row=3, column=1) 

… or just pass the text in directly, without a tkinter variable:

    label = Label(master, text=filevalue)
    label.grid(row=3, column=1) 

There's still one more problem: Every time you call retrieveInput, it's going to create a new Label and grid it in front of whatever used to be there, but you never delete the old ones. So if you press the button over and over again, there will be a whole stack of invisible widgets just wasting resources.

It probably makes more sense to move the label creation to the global scope, just like the text box and the other label, and replace its text in this function, instead of creating a new label each time.

Using a StringVar is the simplest way to do this:

# ...

textBox = Text(master, height=1, width=10)
textBox.grid(row=0, column=1)

fileVar = StringVar()
fileLabel = Label(master, textvariable=fileVar)
fileLabel.grid(row=3, column=1)

def retrieve_input():
    Department = textBox.get("1.0","end-1c") 

    fileread = pd.read_csv('50.csv', encoding='latin-1')
    filevalue = fileread.loc[fileread['Customer'].str.contains("Lam Dep", na=False)]    

    fileVar.set(filevalue)

# ...

You may have other bugs in your code, but I think if you fix these three, you'll at least be pretty close to everything working.

Upvotes: 2

Related Questions