Tkinter Accessing Variables from Different Function - python

Is there a way to access variables from different files if the widget is an Entry? I have tried using the command option but found that was exclusive to Buttons. I'm trying to separate my functions into different files to modulate.
ttk.Label(root, text="How many points do you want to input:").pack()
cell_content = StringVar()
cell_content.trace_add("write", my_tk.retrieve_cell_content)
cell_content_entry = Entry(root, width = 8, textvariable = cell_content)
cell_content_entry.pack()
tkinterFunctions.py
def retrieve_cell_col(self, *args):
global CELL_COL
temp = cell_col.get()
temp = temp.upper()

If I get it right, you want to get your text in Entry widget when it is writing. Not by pushing a Button. please check this if I am right:
from tkinter import *
def call(tex):
print(tex.get())
root = Tk()
tx = StringVar()
tx.trace("w", lambda name, index, mode, tex=tx: call(tex))
entry = Entry(root, textvariable=tx)
entry .pack()
root.mainloop()

Related

tkinter, save the input as variable

I want to use the input value as variable and this is my code.
from tkinter import *
from tkinter import messagebox
window = Tk()
Label(window, text='Cavity number').grid(row=0)
CavNum = StringVar()
for i in range(1,8) :
globals()['L{}_CavNum'.format(i)] = StringVar()
globals()['L{}_CavNum'.format(i)] = Entry(window, textvariable=globals()['L{}_CavNum'.format(i)])
globals()['L{}_CavNum'.format(i)].grid(row=0, column=i)
window.geometry("1200x150")
window.mainloop()
everytime I do print(L1_CavNum), it says "<tkinter.Entry object .!entry>". please tell me what is the problem
You are re-using the same name for the entry widget as you use for StringVar. You could simply change globals()['L{}_CavNum'.format(i)] = StringVar() to globals()['L{}_CavNumSV'.format(i)] = StringVar() and print(L1_CavNum) to print(L1_CavNumSV.get()). However the .get() function will execute when your code runs so you will have to have a button or another event to callback the function.
I would do it like this.
from tkinter import *
def print_vars():
for x in range(len(cavity_string_vars)):
print(cavity_string_vars[x].get())
window = Tk()
Label(window, text='Cavity number').grid(row=0)
cavity_string_vars = []
cavity_entries = []
for i in range(7):
cavity_string_vars.append(StringVar())
cavity_entries.append(Entry(window, textvariable=cavity_string_vars[i]))
cavity_entries[i].grid(row=0, column=i)
print_button = Button(window, text="Print", command=print_vars)
print_button.grid(row=1, column=0)
window.geometry("1200x150")
window.mainloop()
To me associated arrays are much easier than naming each variable even when you program it as you have. Perhaps that is needed for your case.

Adding Checkbutton Options from database with Tkinter Menubutton

I have categories saved in a database on table Geo_Cat. I know my geo_list is getting populated correctly, because I was able to make an OptionMenu earlier. I also printed the list and it worked. So the query is good. However, I need to be able to select more than one option at a time and need to use a MenuButton instead. The options that I need are none and the categories in the table. I've been able to add the "None" checkbutton, but I haven't been able to add the geo_list. Below is a code excerpt:
from Tkinter import *
root = Tk()
location_frame = Frame(root)
location_frame.grid(column=0, row=0, sticky=(N, W, E, S))
location_frame.columnconfigure(0, weight=1)
location_frame.rowconfigure(0, weight=1)
location_frame.pack(pady=25, padx=50)
geo_list= ["geo1","geo2","geo3","geo4"]
amb = Menubutton(location_frame,text="Geo Category", relief=RAISED)
amb.grid(sticky="ew", row=1,column=0)
amb.menu = Menu(amb,tearoff=0)
amb['menu'] = amb.menu
Item0 = IntVar()
amb.menu.add_checkbutton(label="None", variable=Item0)
location_vars = {}
for category in geo_list:
location_vars["Item{0}".format(category)] = IntVar()
amb.menu.add_checkbutton(label=geo_list[category])
amb.pack()
root.mainloop()
I also tried this:
location_vars["Item{0}".format(category)] = IntVar()
amb.menu.add_checkbutton(label=geo_list[category],
variable=location_vars["Item{0}".format(category)])
How can I add my geo_list to the checkbuttons? Any advice would be greatly appreciated.
If you want the items in the geo_list for menu labels, why not just set them; you are already looping over them:
amb.menu.add_checkbutton(label=category)
Also, don't pack amb at the very end; you have already gridded it earlier.
I'm adding an example of how to trace changes associated with each menu item. I have changed the code slightly but I think you will have no problem to get the general idea.
I'm using a BooleanVar() instead of an IntVar(), then each var is saved in location_vars with the key "Item{0}".format(category). Finally I'm setting up a trace for changes in each menu item to to a callback function which will inspect the selections.
Is this what you are after?
from tkinter import *
root = Tk()
amb = Menubutton(root, text="Geo Category", relief=RAISED)
amb.pack(padx=50, pady=25)
amb.menu = Menu(amb, tearoff=0)
amb['menu'] = amb.menu
def callback(*args):
# Callvack function is called when menu items are changed
for key, value in location_vars.items():
print(key, value.get())
print() # To make the printout more readable
geo_list= ["None","geo1","geo2","geo3","geo4"]
location_vars = {}
for category in geo_list:
location_vars["Item{0}".format(category)] = BooleanVar()
# Set "variable" for every menu item
amb.menu.add_checkbutton(label=category,
variable=location_vars["Item{0}".format(category)])
# Trace changes in the variables
location_vars["Item{0}".format(category)].trace("w", callback)
root.mainloop()

tkinter - Changing variables assigned to labels causes duplicate window

I'm using python to interact with some excel spreadsheets. I have all that working and now I'm working on a UI using tkinter. I have 3 buttons one to pull the location of a data file, output file save location and I have a start button.
I'm trying to use a tkinter.Label to display the value of the first two buttons, example "c:/user/data_file". However, when ever I get the variable from the user and try to update the GUI with it, a copy of the window is created with the updated information. I need it to update directly to the current window seamlessly. I've been working to try to resolve this, but I just can't figure it out. Below is the code for my tkinter stuff.
def main():
def InputFilePrompt():
global InputFileLocation
InputFileLocation = askopenfilename()
update()
def OutputFilePrompt():
global OutputFileLocation
OutputFileLocation = filedialog.asksaveasfilename()
update()
def update():
root = Tk()
root.title("test")
root.resizable(width=TRUE,height=TRUE)
InputFile = Button(root, text = "input data", command = InputFilePrompt)
InputFile.grid(row = 0,column = 0)
InputFileValue = Label(root, text = InputFileLocation, bg = 'white')
InputFileValue.grid(row = 1,column = 0)
OutputFile = Button(root, text = "Compiled Data save loacation", command = OutputFilePrompt)
OutputFile.grid(row = 4,column = 0)
OutputFileValue = Label(root, text = "location: N/A", bg = 'white')
OutputFileValue.grid(row = 5,column = 0)
startButton = Button(root, text = "start", bg = 'light green', command = Excel)
startButton.grid(row = 7)
BlankUI = [0 for x in range(2)]
for blankspace in range(2):
BlankUI[blankspace] = Label(root, text = "")
BlankUI[0].grid(row = 2)
BlankUI[1].grid(row = 6)
root.mainloop()
update()
Error:
Here's a version that doesn't create the duplicate window. I've incorporated most of the suggestions I made in comments—except for the one about defining functions inside of other functions. The following still does this because doing so made it very easy to avoid using global variables (which are generally considered a poor programming practice).
Notice that there's no update() function. The values of the two tkinter.Labels are now being stored in two tkinter.StringVars objects instead of in regular Python strings. A StringVar is one of the tkinter so-called "Variable" classes. Their primary feature is that they will cause all widgets referencing them to automatically update themselves whenever their contents get changed. To use them in a Label, they're specified by using the textvariable= option (instead of the text= option) when the constructor is called.
Here's some documentation I found about them with more details on how they work.
import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
def excel():
""" Undefined. """
pass
def main():
def get_input_file_location():
input_file_location.set(askopenfilename())
def get_output_file_location():
output_file_location.set(asksaveasfilename(confirmoverwrite=False))
root = tk.Tk()
root.title('test')
root.resizable(width=True, height=True)
input_file_location = tk.StringVar()
input_file_location.set('<undefined>')
output_file_location = tk.StringVar()
output_file_location.set('<undefined>')
input_file = tk.Button(root, text="Input data",
command=get_input_file_location)
input_file.grid(row=0, column=0)
input_file_value = tk.Label(root, textvariable=input_file_location,
bg='white')
input_file_value.grid(row=1, column=0)
output_file = tk.Button(root, text='Compiled data save loacation',
command=get_output_file_location)
output_file.grid(row=4, column=0)
output_file_value = tk.Label(root, textvariable=output_file_location,
bg='white')
output_file_value.grid(row=5, column=0)
startButton = tk.Button(root, text='start', bg='light green',
command=excel)
startButton.grid(row=7)
blank_ui = [tk.Label(root, text='') for _ in range(2)]
blank_ui[0].grid(row=2)
blank_ui[1].grid(row=6)
root.mainloop()
if __name__ == '__main__':
main()

Label variables for exchange rate calculator [duplicate]

I am having trouble with using a key binding to change the value of a label or any parameter.
This is my code:
from tkinter import*
class MyGUI:
def __init__(self):
self.__mainWindow = Tk()
#self.fram1 = Frame(self.__mainWindow)
self.labelText = 'Enter amount to deposit'
self.depositLabel = Label(self.__mainWindow, text = self.labelText)
self.depositEntry = Entry(self.__mainWindow, width = 10)
self.depositEntry.bind('<Return>', self.depositCallBack)
self.depositLabel.pack()
self.depositEntry.pack()
mainloop()
def depositCallBack(self,event):
self.labelText = 'change the value'
print(self.labelText)
myGUI = MyGUI()
When I run this, I click the entrybox and hit enter, hoping that the label will change value to 'change the value'. However, while it does print that text, the label remains unchanged.
From looking at other questions on similar problems and issues, I have figured how to work with some of this outside a class, but I'm having some difficulties with doing it inside a class.
self.labelText = 'change the value'
The above sentence makes labelText change the value, but not change depositLabel's text.
To change depositLabel's text, use one of following setences:
self.depositLabel['text'] = 'change the value'
OR
self.depositLabel.config(text='change the value')
You can also define a textvariable when creating the Label, and change the textvariable to update the text in the label.
Here's an example:
labelText = StringVar()
depositLabel = Label(self, textvariable=labelText)
depositLabel.grid()
def updateDepositLabel(txt) # you may have to use *args in some cases
labelText.set(txt)
There's no need to update the text in depositLabel manually. Tk does that for you.
Use the config method to change the value of the label:
top = Tk()
l = Label(top)
l.pack()
l.config(text = "Hello World", width = "50")
Here is another one, I think. Just for reference.
Let's set a variable to be an instantance of class StringVar
If you program Tk using the Tcl language, you can ask the system to let you know when a variable is changed. The Tk toolkit can use this feature, called tracing, to update certain widgets when an associated variable is modified.
There’s no way to track changes to Python variables, but Tkinter
allows you to create variable wrappers that can be used wherever Tk
can use a traced Tcl variable.
text = StringVar()
self.depositLabel = Label(self.__mainWindow, text = self.labelText, textvariable = text)
# ^^^^^^^^^^^^^^^^^^^
def depositCallBack(self,event):
text.set('change the value')
I made a small tkinter application which is sets the label after button clicked
#!/usr/bin/env python
from Tkinter import *
from tkFileDialog import askopenfilename
from tkFileDialog import askdirectory
class Application:
def __init__(self, master):
frame = Frame(master,width=200,height=200)
frame.pack()
self.log_file_btn = Button(frame, text="Select Log File", command=self.selectLogFile,width=25).grid(row=0)
self.image_folder_btn = Button(frame, text="Select Image Folder", command=self.selectImageFile,width=25).grid(row=1)
self.quite_button = Button(frame, text="QUIT", fg="red", command=frame.quit,width=25).grid(row=5)
self.logFilePath =StringVar()
self.imageFilePath = StringVar()
self.labelFolder = Label(frame,textvariable=self.logFilePath).grid(row=0,column=1)
self.labelImageFile = Label(frame,textvariable = self.imageFilePath).grid(row = 1,column=1)
def selectLogFile(self):
filename = askopenfilename()
self.logFilePath.set(filename)
def selectImageFile(self):
imageFolder = askdirectory()
self.imageFilePath.set(imageFolder)
root = Tk()
root.title("Geo Tagging")
root.geometry("600x100")
app = Application(root)
root.mainloop()
There are many ways to tackle a problem like this. There are many ways to do this. I'm going to give you the most simple solution to this question I know. When changing the text of a label or any kind of wiget really. I would do it like this.
Name_Of_Label["text"] = "Your New Text"
So when I apply this knowledge to your code. It would look something like this.
from tkinter import*
class MyGUI:
def __init__(self):
self.__mainWindow = Tk()
#self.fram1 = Frame(self.__mainWindow)
self.labelText = 'Enter amount to deposit'
self.depositLabel = Label(self.__mainWindow, text = self.labelText)
self.depositEntry = Entry(self.__mainWindow, width = 10)
self.depositEntry.bind('<Return>', self.depositCallBack)
self.depositLabel.pack()
self.depositEntry.pack()
mainloop()
def depositCallBack(self,event):
self.labelText["text"] = 'change the value'
print(self.labelText)
myGUI = MyGUI()
If this helps please let me know!

Creating a GUI with Tkinter of Python

I have written the following code:
from Tkinter import *
root = Tk()
root.title("Power Method")
labeltext1 = StringVar()
labeltext2 = StringVar()
labeltext1.set('Parameters') # Set start value
labeltext2.set('Epsilon')
label1 = Label (root, textvariable = labeltext1, height = 4)
label1.pack()
Entry(root, textvariable = labeltext1). pack()
label2 = Label (root, textvariable = labeltext2)
label2.pack()
Entry(root, textvariable = labeltext2). pack()
checkBox1 = Checkbutton(root, text = "NumPy")
checkBox1.pack()
checkBox2 = Checkbutton(root, text = "Not NumPy")
checkBox2.pack()
Button(root, text = "Exit").pack(side = RIGHT)
Button(root, text = "Compute").pack(side = RIGHT)
root.mainloop()
This code, when run, creates a window that contains Parameters, Epsilon as two places that you could enter value and NumPy and Not NumPy as checkboxes and finally a compute and exit button.
I am trying to format the code, in a way that Parameters and Epsilon appear on the left of the window, Numpy and Not Numpy infront of them on the right and Compute and Exit stay in their current positions.
Any help regarding the formatting would be appreciated.
Alright you need to google .grid() and .pack() and .place() for tkinter to learn more about what each is good for. For your case you could use any of them, but .grid() is probably the best and easiest for you to use.
To do this you must change .pack() to .grid() everywhere you have it, then you should use the row and column options to put your widgets where you want them. E.G.
label1.grid(row = 1, column = 1)
label2.grid(row = 1, column = 2)
this will put label2 on the right side of label1. The way .grid() works is that the columns are as wide as the largest (widest) widget in that column, same applies for rows.
if you need anything else just ask, but please do look at the documentations as Bryan said.

Categories