When using the feeder button, the script for F runs through entirely through to the print before the 'master' box appears, then does not react to the inputs from the 'master' box. This results in the output being 0.0 kW because the input is a long decimals followed by an L, when what I, the user inputs is 8777
I have been roaming the internet for about a day now with no luck finding anything. I am very new to TK but have been trying to learn it.
def F():
master = tk.Tk()
tk.Label(master, text = 'Feeder Number: ').grid(row=0)
entry1 = tk.Entry(master)
entry1.grid(row=0, column=1)
button2 = tk.Button(master,
text=' Confirm',
command=entry1.get())
button2.pack()
button2.grid(row=0, column=2)
fn = entry1.pack()
print fn
feed = filtered['Feeder']==fn
feedfn = filtered[feed]
Cap = feedfn['AC Name Plate Capacity <= 10kw']
Cap = Cap.astype(float)
AcPv = Cap.sum()
print 'The total PV on this feeder is:', AcPv, 'kW'
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
button = tk.Button(frame,
text='Exit',
fg='red',
command=quit)
button.pack()
button.grid(row=1, column=1)
Fee = tk.Button(frame,
text='Feeder',
command=F)
Fee.pack()
Fee.grid(row=0, column=1)
root.mainloop()
Expected 27.702
Output 0.0
Given that I will not be posting the csv,
entry1/fn should be 8777
currently 'none'
UPDATE
I am now receiving an output of PY_VAR when printing fn, I understand that the code is running all the way through before taking an input. Any recommendations for how to take the input before the filters are run?
def F():
master = tk.Tk()
tk.Label(master, text = 'Feeder Number: ').grid(row=0)
entry1 = tk.Entry(master)
entry1.grid(row=0, column=1)
button2 = tk.Button(master,
text=' Confirm',
command=entry1.get())
button2.grid(row=0, column=2)
fn = tk.IntVar()
print fn
feed = filtered['Feeder']==fn
feedfn = filtered[feed]
Cap = feedfn['AC Name Plate Capacity <= 10kw']
Cap = Cap.astype(float)
AcPv = Cap.sum()
print 'The total PV on this feeder is:', AcPv, 'kW'
For those interested in the final code (Which worked for me):
def F():
master = tk.Tk()
tk.Label(master, text = 'Feeder Number: ').grid(row=0)
entry = tk.Entry(master)
entry.grid(row=0, column=1)
def pint():
data = entry.get()
master.destroy()
feed = filtered['Feeder']==data
feedfn = filtered[feed]
Cap = feedfn['AC Name Plate Capacity <= 10kw']
Cap = Cap.astype(float)
AcPv = Cap.sum()
fdf = tk.Tk()
tk.Label(fdf, text = AcPv).grid(row=0)
button4 = tk.Button(fdf,
text = ' Exit',
fg='red',
command=fdf.destroy)
button4.grid(row=1)
button2 = tk.Button(master,
text=' Confirm',
command = pint)
button2.grid(row=0, column=2)
button3 = tk.Button(master,
text = ' Exit',
fg='red',
command=master.destroy)
button3.grid(row=0, column=3)
master.mainloop()
There a few mistake in your code that lead to the different output you have received.
First, why is your code executing without showing the master box :
Your tkinter need a mainloop() call if you want a persistent window.
master.mainloop()
You did that right with your root, but your master lacks that mainloop. This line is what basically keeping your GUI alive and looping over it for changes until it is destroyed one way or another. You need to add this line after creating your widgets in order to be able to interact with the window. Anything written after this line (but still indented in the definition) will be executed when your window is closed, either manually or with the command :
master.destroy()
Next, although this will yield a working window, you can still interact with your root window while the master window is up, which can lead to problems if you are expecting variable from master. I suggest you read about the Toplevel widget which is made specifically for cases like yours. (http://effbot.org/tkinterbook/toplevel.htm) Alternatively, you could also use tkinter's tkSimpleDialog.askinteger or askfloat functions which seems perfect for your application.
Finally, the entry allows you to write text but how to access the text? you can use Entry1.get() to extract the content of the entry, or as you have started to to in your update, you can assign a tkinter variable to the entry. This variable will be updated as you change write strings or numbers in the entry. To bind the variable to your entry, you must state it in the entry's creation :
fn = tk.StringVar(value = '000')
entry1 = tk.Entry(master, textvariable = fn)
*Note, this will require your fn variable to be initialized before the entry. Also, you can initialize a value for that variable upon creation
the tkinter variable is an object which is why when you print it, you get PY_VAR. (the type of object) To access the value, you need to use the get() method :
print(fn.get())
Related
I'm trying to create a function in tkinter where I can print out what the user writes in a Entry box. I'm able to print out ask_an_entry_get, but when I try to print what_is_answer_entry_get
, I get nothing my empty spaces.
Please find out the problem here. Also I'm using the Entry widget, along with the get() function, to get input from the user.
def answer_quizmaker_score():
print(ask_an_entry_get)
print(what_is_answer_entry_get)
I made a lot of global variables so I could use them all around my code.
global what_is_answer_entry
what_is_answer_entry = Entry(root4)
what_is_answer_entry.pack()
I then used the get() function to retrieve what the user typed.
global what_is_answer_entry_get
what_is_answer_entry_get = what_is_answer_entry.get()
This is the exact process I did for both ask_an_entry_get and what_is_answer_entry_get. However for some reason only ask_an_entry_get is printed, while what_is_answer_entry_get is printing nothing in the console.
from tkinter import *
root = Tk()
root.geometry("500x500")
txt1 = StringVar()
txt2 = StringVar()
def txt_printer():
print(txt1.get())
print(txt2.get())
x = Entry(root, textvariable=txt1, width=20)
x.place(x=0, y=0)
y = Entry(root, textvariable=txt2, width=20)
y.place(x=0, y=50)
btn_print = Button(root, text="print", command=txt_printer)
btn_print.place(x=0, y=100)
# Or if you want to show the txt on window then:
def txt_on_window():
lb1 = Label(root, text=txt1.get())
lb1.place(x=0, y=200)
lb2 = Label(root, text=txt2.get())
lb2.place(x=0, y=235)
btn_print_on_window = Button(root, text="print on screen", command=txt_on_window)
btn_print_on_window.place(x=0, y=150)
root.mainloop()
I'm using Tkinter for the GUI for my project (if you type ingredients you want into a textbox, it will return recipes using API.. and so on). I'm trying to save the user input into a variable so that I can use it later. However, the get() function seems like not catching anything. I've read a different post but not sure what I'm doing it wrong. Here is my code:
import tkinter as tk
import tkinter.font as font
# globally declare the expression variable
expression = ""
def getSentence():
global expression
# clear the entry fields
deleteEntryFields()
# ask a question
field2.insert(0, 'What do you want to eat? You can express and we will find something for you!')
expression = v.get()
return expression
def getIngredients():
pass
def searchWithSentence(sentence):
pass
def searchIngredients(ingredients):
pass
################################################################################
# This is where I'm testing if the user input is saved to a variable expression.
def enter():
field1.insert(0, str(expression))
print(expression)
################################################################################
def clear():
global expression
expression = ""
def deleteEntryFields():
field1.delete(0, 'end')
field2.delete(0, 'end')
# Driver code
if __name__ == "__main__":
# create a GUI window
master = tk.Tk()
v = tk.StringVar()
field1 = tk.Entry(master, textvariable=v)
field2 = tk.Entry(master)
field1.insert(0, 'Please type here')
field2.insert(0, 'Results will be shown here.')
field1.place(x=20, y=20, width=730, height=50)
field2.place(x=20, y=80, width=730, height=500)
# set the background colour of GUI window
master.configure(background="lemon chiffon")
# set the title of GUI window
master.title("Recipe Finder")
# set the configuration of GUI window
master.geometry("1050x600")
# set font
myFont = font.Font(family='Verdana', size=9, weight='bold')
# Buttons
button1 = tk.Button(master, text=' What do you feel like eating? ', fg='black', bg='salmon',
command=getSentence, height=5, width=30)
button1.place(x=770, y=100)
button1['font'] = myFont
button2 = tk.Button(master, text=' Type the ingredients you have! ', fg='black', bg='orange',
command=getIngredients, height=5, width=30)
button2.place(x=770, y=200)
button2['font'] = myFont
Clear = tk.Button(master, text=' CLEAR ', fg='black', bg='white',
command=clear, height=5, width=30)
Clear.place(x=770, y=300)
Clear['font'] = myFont
Enter = tk.Button(master, text=' ENTER ', fg='black', bg='white',
command=enter, height=5, width=30)
Enter.place(x=770, y=400)
Enter['font'] = myFont
# start the GUI
master.mainloop()
Previously I was not using StringVar(), but when I did some research, it says it can be one of the ways to get the get() function worked. But nothing happened... How can I effectively get user input and save it to global variable?
Any advice will be appreciated!
You are using the Entry itself to contain an explanation what to type?
To make that work you could bind a callback that clears the entry to the <FocusIn> event.
This will make sure that the entry field is empty when the user wants to type something.
And to be consistent, you would have to restore that text on a <FocusOut> event in the case that the user didn't fill in anything.
While this is used in places where screen space is extremely limited, it doesn't feel like good UI design.
A more common method is to put a Label with a description before the Entry.
i am developing an application to calculate some taxes and show the result in the graphical interface. The code itself works perfectly, but if i use numbers with bigger squares, the result overlaps over the previous one. My question is, is it possible to clear the previous result and calculate the new one?
Follow the complete code below:
from tkinter import *
root = Tk()
l_vlrRec = Label(root, text='Receita')
l_vlrRec.place(x=10, y=10)
e_vlrRec = Entry(root)
e_vlrRec.place(x=75, y=10, width=75)
def calcular():
receita = float(e_vlrRec.get())
l_result = Label(root, text='{:.2f}'.format(receita))
l_result.place(x=10, y=150)
e_vlrRec.delete(0, END)
bt = Button(root, text='Calcular', command=calcular)
bt.place(x=10, y=50)
root.mainloop()
You can use the label's textvariable and also you don't have to instantiate a new Label every time the button is pressed:
v_result = DoubleVar()
l_result = Label(root, textvariable=v_result)
l_result.place(x=10, y=150)
def calcular():
v_result.set(round(float(e_vlrRec.get()),2))
You can do the same for your Entry object e_vlrRec so you don't have to cast the string you get by calling e_vlrRec.get() but use the variable's get() instead
Without using textvariable you can also reconfigure the label's text parameter:
l_result.configure(text='{:.2f}'.format(receita))
or
l_result['text'] = '{:.2f}'.format(receita)
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
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.
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:
You are defining an inner function printSomething which is never called.
Even if you were calling printSomething you are going to create a new Label every time you press button1.
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.
I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()