Python How to use entry text value in another function using GUI - python

I am using tkinter GUI. Created GUI, Now at one of my GUI ask Input value and I need to display that Input Value in another function and print that value.
Code is as below:
def EventOnBtnIO():
#some commutation
ForceNumericItem() #Called the function to open the new GUI
request = 'FF'+Value
print request
return
This is my GUI which consists of entry box and buttons
def ForceNumericItem():
global Subtop
Subtop = Toplevel(top)
Subtop.geometry("350x110+500+200")
Subtop.title("Force Numeric Items")
Subtop.grab_set()
frame = Frame(Subtop,width=15, height=200,bd = 1)
frame.pack(fill = 'both',padx=3, pady=3)
# frame.config(relief=RIDGE)
global entry2
global entrytext2
entrytext2 = IntVar()
entry2 = Entry(frame,textvariable=entrytext2, width = 45)
entry2.pack(padx = 5, pady = 5)
entry2.focus_set()
entry2.selection_range(0, END)
topButtonShow = Button(frame, text = 'OK',command = ForceValue,width = 10)
topButtonBack = Button(frame, text = 'Cancel',command = okclose,width = 10)
topButtonShow.pack(side = LEFT,padx=45,pady=5)
topButtonBack.pack(side = RIGHT,padx=45,pady=5)
return
After OK click, it should take the Value and display in my EventOnBtnIO function
def ForceValue():
global Value
Value = int(entrytext2.get())
print Value
Subtop.destroy()
top.deiconify()
return
I think it is related to local or global varibale, but not able to fix it. Getting value now
FF
Expected value
FF + Value

The function in which you create your popup window returns before the user has input a number in it. To fix this, you could use the .wait_window() method:
def EventOnBtnIO():
ForceNumericItem()
top.wait_window(Subtop)
request = 'FF'+str(Value)
print request

Related

Why can't I specific the default selected radiobutton?

I am making a simple GUI using Python's tkinter module, and I'm having a lot of trouble with radiobuttons. I wish to have the first selected by default, but the other two are selected at the start. Additionally, when I just pass the cursor over the window, the first one becomes checked (I do not click) so all 3 show as selected. My code:
import tkinter as tk
class openGUI(object):
def __init__(self):
# title of window
window.title("DUNE LArTPC Simulator")
# label for choices
self.question = tk.Label(window, text = "Do you want to create new or analyse existing data?")
self.question.grid(row = 0, column = 0, columnspan = 3)
# buttons corresponding to choices
self.createBtn = tk.Button(window, text = "Create", command = self.createData)
self.analyseBtn = tk.Button(window, text = "Analyse", command = self.analyseData)
self.createBtn.grid(row = 1, column = 0)
self.analyseBtn.grid(row = 1, column = 2)
def analyseData(self):
"""
Not implemented yet.
"""
pass
def createData(self):
# edit window to display new widgets (irritating to have lots of windows open!)
window.title("Select variable")
self.question.destroy()
self.createBtn.destroy()
self.analyseBtn.destroy()
# text in window
variableQ = tk.Label(window, text = "Please select Independent variable for dataset:")
variableQ.grid(row = 0, column = 0, columnspan = 3)
# radioselect variable
selection = tk.StringVar()
selection.set("lifetime")
# radioselect buttons
lifetimeBtn = tk.Radiobutton(window, variable = selection, value = "lifetime", text = "Lifetime")
elecNoiseBtn = tk.Radiobutton(window, variable = selection, value = "electronic", text = "Electronic Noise")
radioactivityBtn = tk.Radiobutton(window, variable = selection, value = "radioactive", text = "Radioactivity")
lifetimeBtn.grid(row = 1, column = 0)
elecNoiseBtn.grid(row = 1, column = 1)
radioactivityBtn.grid(row = 1, column = 2)
# create window
window = tk.Tk()
# create class object with methods to populate
# window with widgets
initWin = openGUI()
# enter mainloop
window.mainloop()
Running the above gives me:
I have tried using lifetimeBtn.select() method instead of setting the StringVar(), but this does not seem to work either. What have I missed?
EDIT: added rest of code to show how I am using class and functions to manipulate the window.
It is because selection is a local variable inside createData() function and it will be garbage collected after function completes.
Change selection to instance variable self.selection.

Clear text from tkinter entry widget

I am using Tkinter entry widgets to allow users to input text to a GUI. The entry widgets have default text which I would like to clear with a single button press. I have the following code:
from Tkinter import *
def delete_entries(fields):
for field in fields:
field.delete(0,END)
def UserInput(status,name):
optionFrame = Frame(root)
optionLabel = Label(optionFrame)
optionLabel["text"] = name
optionLabel.pack(side=LEFT)
var = StringVar(root)
var.set(status)
w = Entry(optionFrame, textvariable= var)
w.pack(side = LEFT)
optionFrame.pack()
if __name__ == '__main__':
root = Tk()
fields = 'ExperimentNumber', 'OutputFileName', 'npts1', 'block1'
ExperimentNumber = UserInput("1", "Experiment number")
OutputFileName = UserInput("output.txt", "Output file name")
npts1 = UserInput("1000", "Number of points")
block1 = UserInput("8", "Block size")
Delete_button = Button(root, text = 'Clear all', command = delete_entries(fields))
Delete_button.pack()
I have tried creating fields with the list of variables that I want to delete (as above) and iterating over this in the function delete_entries(), however this returns an error because the entries in fields are strings. I have tried replacing fields with fields = ExperimentNumber for example, but this returns an error because ExperimentNumber hasn't yet been defined. Finally I tried putting ExperimentNumber within the delete function i.e.
def delete_entries():
ExperimentNumber.delete(0,End)
but this doesn't work because ExperimentNumber has the attribute NoneType (I don't understand why this is, because the delete_entries() function isn't called until after the ExperimentNumber Entry widget is created via the function UserInput). How can I go about deleting all the text in the Entry widgets? I have about 20 of these in my actual code and would like the user to be able to clear all the fields with one button press.
You are on the right track but you missed two little things. I added those two in your code and tried to explain with comments.
from Tkinter import *
def delete_entries():
for field in fields:
field.delete(0,END)
def UserInput(status,name):
optionFrame = Frame(root)
optionLabel = Label(optionFrame)
optionLabel["text"] = name
optionLabel.pack(side=LEFT)
var = StringVar(root)
var.set(status)
w = Entry(optionFrame, textvariable= var)
w.pack(side = LEFT)
optionFrame.pack()
return w
#this return is crucial because if you don't return your widget's identity,
#you can not use them in another function
if __name__ == '__main__':
root = Tk()
ExperimentNumber = UserInput("1", "Experiment number")
OutputFileName = UserInput("output.txt", "Output file name")
npts1 = UserInput("1000", "Number of points")
block1 = UserInput("8", "Block size")
#you are saying it does not work because of they are strings.
#then don't assign strings to fields. assign variables.
fields = ExperimentNumber, OutputFileName, npts1, block1
#since fields is defined in global scope, you don't need to use it as parameter
Delete_button = Button(root, text = 'Clear all', command = delete_entries)
Delete_button.pack()
root.mainloop()

Updating Text In Entry (Tkinter)

The piece of code below takes input from user through a form and then returns the input as multiplied by 2. What I want to do is, when a user types a number (for example 5) and presses the "Enter" key on keyboard or clicks on "Calculate" button, the place where he entered the number "5" should also display 10, besides the place immediately below. Normally, the form keeps the number entered , but the place right below it gets updated and displays 10 (let us say you have entered 5)
How can I also update the form place?
(Please let me know if my question is unclear, so I can better explain myself.)
from tkinter import *
def multiplier(*args):
try:
value = float(ment.get())
result.set(value * 2)
except ValueError:
pass
mGui = Tk()
mGui.geometry("300x300+300+300")
ment = StringVar()
result = StringVar()
mbutton = Button (mGui, text = "Calculate", command = multiplier)
mbutton.pack()
mEntry = Entry(mGui, textvariable = ment, text="bebe")
mEntry.pack()
mresult = Label(mGui, textvariable = result)
mresult.pack()
You can use Entry's delete and insert methods.
from tkinter import *
def multiplier(*args):
try:
value = float(ment.get())
res = value *2
result.set(res)
mEntry.delete(0, END) #deletes the current value
mEntry.insert(0, res) #inserts new value assigned by 2nd parameter
except ValueError:
pass
mGui = Tk()
mGui.geometry("300x300+300+300")
ment = StringVar()
result = StringVar()
mbutton = Button (mGui, text = "Calculate", command = multiplier)
mbutton.pack()
mEntry = Entry(mGui, textvariable = ment, text="bebe")
mEntry.pack()
mresult = Label(mGui, textvariable = result)
mresult.pack()
The StringVars you update via the set method, which you're doing in the multiplier function. So you question is how to trigger the call the multiplier when the user presses enter, you can use:
mGui.bind('<Return>', multiplier)
Do you also want to change the text in the Entry? The question is a bit unclear. You can do that via ment.set as well.

Trying to put drop down list on a code using Tkinter

I'm tring to put some drop down list on a graphic interface I'm building.
I've found the following code for a drop down list, but I'm not able to adapt it to my code.
from Tkinter import *
def print_it(event):
print var.get()
root = Tk()
var = StringVar()
var.set("a")
OptionMenu(root, var, "a","b","c", command=print_it).pack()
root.mainloop()
This is my code, it's quite simple what I've done so far. A menu shows up, it asks for how many (n) components does the users want to enter, and it shows n options to entry. The code above shows 'blank' entrys after you put the desired number of components. I want to replace those three blank entrys with three drop down list.
It's marked when I want to put those dropdown lists.
from Tkinter import *
import Image
import ImageTk
import tkFileDialog
class Planificador:
def __init__(self,master):
master.title("Planificador")
self.frameOne = Frame(master)
self.frameOne.grid(row=0,column=0)
# Logo
self.imgLabel = Label(self.frameOne, image = None)
self.imgLabel.grid(row=0,column=0)
self.img = ImageTk.PhotoImage(file = "logo.png")
self.imgLabel["image"] = self.img
self.botones()
def botones(self):
self.piezastext = Label(self.frameOne, text = " number of components ", justify="center")
self.piezastext.grid(row=1, column=0)
self.entrypiezas = Entry(self.frameOne,width=5)
self.entrypiezas.grid(row=2, column=0)
self.aceptarnumpiezas = Button(self.frameOne,text="Aceptar", command=self.aceptar_piezas,width=8)
self.aceptarnumpiezas.grid(row=6, column=0)
def aceptar_piezas(self):
num_piezas = self.entrypiezas.get()
print num_piezas
self.piezastext.grid_remove()
self.entrypiezas.grid_remove()
self.aceptarnumpiezas.grid_remove()
n = 1;
while n <= int(num_piezas):
self.textopieza = Label(self.frameOne, text = "Pieza", justify="left")
self.textopieza.grid(row=n, column=0)
// INSTEAD THESE 'n' BLANK ENTRYS, I WANT TO PUT 'n' DROP DOWN LISTS
self.entrypiezas = Entry(self.frameOne,width=5)
self.entrypiezas.grid(row=n, column=1)
self.aceptarpiezas = Button(self.frameOne,text="Aceptar",width=8)
self.aceptarpiezas.grid(row=int(num_piezas)+1, column=0)
n += 1
# Main
if __name__ == "__main__":
# create interfacE
root = Tk()
movieApp = Planificador(root)
root.mainloop()
So I want to know how can I put that drop down list on a given frame, frameOnein my case, instead of a full window. Thanks in advance.
I modified your aceptar_piezas function to do what I think you want:
def aceptar_piezas(self):
num_piezas = self.entrypiezas.get()
print num_piezas
self.piezastext.grid_remove()
self.entrypiezas.grid_remove()
self.aceptarnumpiezas.grid_remove()
# Create a list of tuples to hold the dynamically created Optionmenus
# The first item in the tuple is the menu, the second is its variable
self.optionmenus = list()
n = 1
while n <= int(num_piezas):
self.textopieza = Label(self.frameOne, text = "Pieza", justify="left")
self.textopieza.grid(row=n, column=0)
# Variable for the Optionmenu
var = StringVar()
# The menu
menu = OptionMenu(self.frameOne, var, "a","b","c")
menu.grid(row=n, column=1)
# Set the variable to "a" as default
var.set("a")
# Add the menu to the list of Optionmenus
self.optionmenus.append((menu, var))
n += 1
def clicked():
"""This function was made just to demonstrate. It is hooked up to the button"""
for optionmenu in self.optionmenus:
print optionmenu[1].get()
print self.optionmenus
# This button doesn't need to be in the while loop
self.aceptarpiezas = Button(self.frameOne, text="Aceptar", command=clicked, width=8)
self.aceptarpiezas.grid(row=int(num_piezas)+1, column=0)
The tuples in the list are in the order that the Optionmenus were created. So, the first tuple contains the data for the first Optionmenu, the second for the second, and so forth.

python tkinter return value from function used in command [duplicate]

This question already has answers here:
Python - returning from a Tkinter callback
(3 answers)
Closed 4 months ago.
how do i get the return value A to C? I am not using class by the way.
def button:
mylabel = Label(myGui, text = "hi").grid(row = 0, column = 0)
A = B.get()
return A
B = StringVar()
C = ""
myentry = Entry(myGui, textvariable = B).grid(row = 1, column = 0)
Submit = Button(myGui, text = "Submit", command = button).grid(row = 1, column = 1)
Short answer: you cannot. Callbacks can't return anything because there's nowhere to return it to -- except the event loop, which doesn't do anything with return values.
In an event based application, what you typically will do is set an attribute on a class. Or, if you're a beginner, you can set a global variable. Using a global variable isn't a good idea for real code that has to be maintained over time but it's OK for experimentation.
So, for example, since C appears to be a global variable in your example, you would do something like:
def button():
global C
mylabel = Label(myGui, text = "hi").grid(row = 0, column = 0)
A = B.get()
C = A
You could call C.set from within the button function:
def button:
mylabel = Label(myGui, text = "hi").grid(row = 0, column = 0)
A = B.get()
C.set(A)
# return A # return values are useless here
it's easy just declare A a global.
def button:
global A
mylabel = Label(myGui, text = "hi").grid(row = 0, column = 0)
A = B.get()
return A
B = StringVar()`
C = ""
myentry = Entry(myGui, textvariable = B).grid(row = 1, column = 0)
Submit = Button(myGui, text = "Submit", command = button).grid(row = 1, column = 1)
# and then A is not empty
B= A
You create a child class of Tkinter.Tk, and define a member variable self.A in that class. Then you can mimic return behavior by
self.A = B.get()
See, Return values of Tkinter text entry, close GUI
The Answer 3 is the best Option.
But I think that happen a little error (maybe in python 3).
You have to write:
Submit = Button(myGui, text = "Submit", command = lambda:C==button()).grid(row
= 1, column = 1)
Look the double "==" in "lambda: C==...".
Does work.
So the code colud be:
def button():
mylabel = Label(myGui, text = "hi").grid(row = 0, column = 0)
A = B.get()
return A
B = StringVar()
C = ""
myentry = Entry(myGui, textvariable = B).grid(row = 1, column = 0)
Submit = Button(myGui, text = "Submit", command = lambda: C==button()).grid(row = 1, column = 1)
(............. and the rest of the code)
There are two ways to do it: 1) a global variable 2) to store the variable you want to return in another class:
1)
define the function you use in a button:
def yourFunction (x):
global variab
variab = x
Transfer the function to your button:
button = Button (root, command=lambda: yourFunction (x))
I know that you don't like to use too many globals, so there's a second solution:
create a class storing the returned variable:
class ClassToStoreReturnedVariable:
def __init__ (self):
self.returnedVariable = None
def returnVariable (self, x):
self.returnedVariable = x
returnedVariable = ClassToStoreReturnedVariable ()
class YourButton:
def __init__ (self):
self.anotherThing = None
self.button = Button (root, command=lambda: returnedVariable.returnVariable (x))
self.pack ()
The button must be written in the end of a button class, because you may want to create a function using self. Such function won't work, if init doesn't create self, before you transfer the function to the button. And don't forget to pack or grid it.
The only known way to get the return value of a button command is by using button.invoke(). Tkinter wraps the button command in a tcl function, but the wrapped function returns whatever the original function returns. See the source code:
def invoke(self):
"""Invoke the command associated with the button.
The return value is the return value from the command,
or an empty string if there is no command associated with
the button. This command is ignored if the button's state
is disabled.
"""
return self.tk.call(self._w, 'invoke')
Example:
import tkinter as tk
def command():
return 'value'
root=tk.Tk()
b = tk.Button(root, text='example', command=command)
b.pack()
value = b.invoke()
print(value)
root.mainloop()
Old question, but most answers suggested a global variable. I don't like using too many global variables in my projects, so here's my solution.
When declaring your Tkinter button, you can use a lambda function as the command. This lambda can interact with variables that are within the same namespace as the button you are defining. Be sure to define this variable before initializing the button.
def button():
mylabel = Label(myGui, text = "hi").grid(row = 0, column = 0)
A = B.get()
return A
B = StringVar()
C = ""
myentry = Entry(myGui, textvariable = B).grid(row = 1, column = 0)
Submit = Button(myGui, text = "Submit", command = lambda: C=button()).grid(row = 1, column = 1)
You may need to have self as an argument for button depending on your project organization, but the concept is the same. Lambda commands are also useful for passing arguments to the button command.

Categories

Resources