Label variables for exchange rate calculator [duplicate] - python

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!

Related

Tkinter Accessing Variables from Different Function

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()

Update the window with a OptionMenu in tkinter

I am looking for a way to change the content of the window based on what option you select in the OptionMenu. It should have 3 different options, namely "Introduction", "Encrypt" and "Decrypt". I've the code to create an OptionMenu but now I wanna know how can I modify them to show a different page, depending on the one who is selected. Could someone help me with that? I am using python 3
so for example:
from tkinter import *
OptionList = [
"Einführung",
"Verschlüsseln",
"Entschlüsseln"
]
window = Tk()
window.geometry('200x200')
variable = StringVar(window)
variable.set(OptionList[0])
opt = OptionMenu(window, variable, *OptionList)
opt.config(width=90, font=('Calbri', 12))
opt.pack(side="top")
window.mainloop()
This will produce a window with a OptionMenu with the three options I wrote above (just in German) and now I'd like to change the page depending on the current chosen option of the OptionMenu
Thanks guys!
This is now the forth edit or something, but thats the final solution i've come up with.
#coding=utf-
import tkinter as tk
from tkinter import *
window = Tk()
window.geometry('200x200')
OptionList = ["Einführung", "Verschlüsseln", "Entschlüsseln"]
class App:
def __init__(self, master):
self.choice_var = tk.StringVar()
self.choice_var.set(OptionList[0])
opt = OptionMenu(window, self.choice_var, *OptionList, command=self.switch)
opt.config(width=90, font=('Calbri', 12))
opt.pack(side="top")
self.random_label1 = tk.Label(window, text="Welcome content here")
self.random_label2 = tk.Label(window, text="Encrypt content here")
self.random_label3 = tk.Label(window, text="Decrypt content here")
self.random_label1.pack()
self.random_label2.pack()
self.random_label3.pack()
self.label_info1 = self.random_label1.pack_info()
self.label_info2 = self.random_label2.pack_info()
self.label_info3 = self.random_label3.pack_info()
self.switch()
def switch(self, *args):
var = str(self.choice_var.get())
if var == "Einführung":
self.random_label1.pack(self.label_info1)
self.random_label2.pack_forget()
self.random_label3.pack_forget()
if var == "Verschlüsseln":
self.random_label2.pack(self.label_info2)
self.random_label1.pack_forget()
self.random_label3.pack_forget()
if var == "Entschlüsseln":
self.random_label3.pack(self.label_info3)
self.random_label2.pack_forget()
self.random_label1.pack_forget()
myApp = App(window)
window.mainloop()

Python3 Print Tuple in another class [duplicate]

I am trying to set the text of an Entry widget using a button in a GUI using the tkinter module.
This GUI is to help me classify thousands of words into five categories. Each of the categories has a button. I was hoping that using a button would significantly speed me up and I want to double check the words every time otherwise I would just use the button and have the GUI process the current word and bring the next word.
The command buttons for some reason are not behaving like I want them to. This is an example:
import tkinter as tk
from tkinter import ttk
win = tk.Tk()
v = tk.StringVar()
def setText(word):
v.set(word)
a = ttk.Button(win, text="plant", command=setText("plant"))
a.pack()
b = ttk.Button(win, text="animal", command=setText("animal"))
b.pack()
c = ttk.Entry(win, textvariable=v)
c.pack()
win.mainloop()
So far, when I am able to compile, the click does nothing.
You might want to use insert method. You can find the documentation for the Tkinter Entry Widget here.
This script inserts a text into Entry. The inserted text can be changed in command parameter of the Button.
from tkinter import *
def set_text(text):
e.delete(0,END)
e.insert(0,text)
return
win = Tk()
e = Entry(win,width=10)
e.pack()
b1 = Button(win,text="animal",command=lambda:set_text("animal"))
b1.pack()
b2 = Button(win,text="plant",command=lambda:set_text("plant"))
b2.pack()
win.mainloop()
If you use a "text variable" tk.StringVar(), you can just set() that.
No need to use the Entry delete and insert. Moreover, those functions don't work when the Entry is disabled or readonly! The text variable method, however, does work under those conditions as well.
import Tkinter as tk
...
entry_text = tk.StringVar()
entry = tk.Entry( master, textvariable=entry_text )
entry_text.set( "Hello World" )
You can choose between the following two methods to set the text of an Entry widget. For the examples, assume imported library import tkinter as tk and root window root = tk.Tk().
Method A: Use delete and insert
Widget Entry provides methods delete and insert which can be used to set its text to a new value. First, you'll have to remove any former, old text from Entry with delete which needs the positions where to start and end the deletion. Since we want to remove the full old text, we start at 0 and end at wherever the end currently is. We can access that value via END. Afterwards the Entry is empty and we can insert new_text at position 0.
entry = tk.Entry(root)
new_text = "Example text"
entry.delete(0, tk.END)
entry.insert(0, new_text)
Method B: Use StringVar
You have to create a new StringVar object called entry_text in the example. Also, your Entry widget has to be created with keyword argument textvariable. Afterwards, every time you change entry_text with set, the text will automatically show up in the Entry widget.
entry_text = tk.StringVar()
entry = tk.Entry(root, textvariable=entry_text)
new_text = "Example text"
entry_text.set(new_text)
Complete working example which contains both methods to set the text via Button:
This window
is generated by the following complete working example:
import tkinter as tk
def button_1_click():
# define new text (you can modify this to your needs!)
new_text = "Button 1 clicked!"
# delete content from position 0 to end
entry.delete(0, tk.END)
# insert new_text at position 0
entry.insert(0, new_text)
def button_2_click():
# define new text (you can modify this to your needs!)
new_text = "Button 2 clicked!"
# set connected text variable to new_text
entry_text.set(new_text)
root = tk.Tk()
entry_text = tk.StringVar()
entry = tk.Entry(root, textvariable=entry_text)
button_1 = tk.Button(root, text="Button 1", command=button_1_click)
button_2 = tk.Button(root, text="Button 2", command=button_2_click)
entry.pack(side=tk.TOP)
button_1.pack(side=tk.LEFT)
button_2.pack(side=tk.LEFT)
root.mainloop()
Your problem is that when you do this:
a = Button(win, text="plant", command=setText("plant"))
it tries to evaluate what to set for the command. So when instantiating the Button object, it actually calls setText("plant"). This is wrong, because you don't want to call the setText method yet. Then it takes the return value of this call (which is None), and sets that to the command of the button. That's why clicking the button does nothing, because there is no command set for it.
If you do as Milan Skála suggested and use a lambda expression instead, then your code will work (assuming you fix the indentation and the parentheses).
Instead of command=setText("plant"), which actually calls the function, you can set command=lambda:setText("plant") which specifies something which will call the function later, when you want to call it.
If you don't like lambdas, another (slightly more cumbersome) way would be to define a pair of functions to do what you want:
def set_to_plant():
set_text("plant")
def set_to_animal():
set_text("animal")
and then you can use command=set_to_plant and command=set_to_animal - these will evaluate to the corresponding functions, but are definitely not the same as command=set_to_plant() which would of course evaluate to None again.
One way would be to inherit a new class,EntryWithSet, and defining set method that makes use of delete and insert methods of the Entry class objects:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
class EntryWithSet(tk.Entry):
"""
A subclass to Entry that has a set method for setting its text to
a given string, much like a Variable class.
"""
def __init__(self, master, *args, **kwargs):
tk.Entry.__init__(self, master, *args, **kwargs)
def set(self, text_string):
"""
Sets the object's text to text_string.
"""
self.delete('0', 'end')
self.insert('0', text_string)
def on_button_click():
import random, string
rand_str = ''.join(random.choice(string.ascii_letters) for _ in range(19))
entry.set(rand_str)
if __name__ == '__main__':
root = tk.Tk()
entry = EntryWithSet(root)
entry.pack()
tk.Button(root, text="Set", command=on_button_click).pack()
tk.mainloop()
e= StringVar()
def fileDialog():
filename = filedialog.askopenfilename(initialdir = "/",title = "Select A
File",filetype = (("jpeg","*.jpg"),("png","*.png"),("All Files","*.*")))
e.set(filename)
la = Entry(self,textvariable = e,width = 30).place(x=230,y=330)
butt=Button(self,text="Browse",width=7,command=fileDialog).place(x=430,y=328)

Tkinter: is there a way to check checkboxes by default?

I have this piece of code that will create a simple checkbox :
from Tkinter import *
CheckVar = IntVar()
self.checkbutton = Checkbutton(self.root, text = "Test", variable = CheckVar)
However this checkbox in unchecked by default and I'm searching for a way to check it.
So far I have tried to insert
CheckVar.set(1)
right after CheckVar but it didn't work.
Thanks for your help
Edit : here is my full piece of code. When I run it, the box is still unchecked
from Tkinter import *
class App():
def __init__(self, root):
self.root = root
CheckVar = IntVar()
CheckVar.set(1)
self.checkbutton = Checkbutton(self.root, text = "Test", variable = CheckVar)
self.checkbutton.grid(row=0, column=0,)
root = Tk()
app = App(root)
root.mainloop()
Your CheckVar is a local variable. It's getting garbage collected. Save it as an object attribute. Also, you can create the variable and initialize it all in one step:
self.CheckVar = IntVar(value=1)
self.checkbutton = Checkbutton(..., variable = self.CheckVar)
You can also use the select function of the checkbutton:
self.checkbutton.select()
I think the function you are looking for is .select()
This function selects the checkbutton (as can be assumed from the function name)
Try calling this function after your widget is defined:
from Tkinter import *
CheckVar = IntVar()
self.checkbutton = Checkbutton(self.root, text = "Test", variable = CheckVar)
self.checkbutton.select()
By calling the function right after the widget is created, it looks as though it's selected by default.
Just adding onto GunnerStone's answer - Because I was looking for something where I can reset my values/checkboxes.
If you'd like to de-select the checkbox value for whatever reason, use deselect():
from Tkinter import *
CheckVar = IntVar()
self.checkbutton = Checkbutton(self.root, text = "Test", variable = CheckVar)
self.checkbutton.deselect()
or use toggle to switch between the two:
self.checkbutton.toggle()
I was using ttk and the only thing that worked was
self.checkbutton.state(["selected"])
Check the state via
"selected" in self.checkbutton.state()
var4 = IntVar(value=1)
Checkbutton(root, text="New", variable=var4, bg="light green").grid(row=12, column=0)
This will check all the check boxs.

Using the variable from entry/button in another function in Tkinter

When I press the button, I want it to get the Entry and -for future things- use it in another function.
import tkinter
def ButtonAction():
MyEntry = ent.get() #this is the variable I wanna use in another function
den = tkinter.Tk()
den.title("Widget Example")
lbl = tkinter.Label(den, text="Write Something")
ent = tkinter.Entry(den)
btn = tkinter.Button(den, text="Get That Something", command = ButtonAction )
lbl.pack()
ent.pack()
btn.pack()
den.mainloop()
print MyEntry #something like this maybe. That's for just example
I will use this thing as a search tool. Entry window will appear, get that "entry" from there and search it in files like:
if MyEntry in files:
#do smth
I know I can handle the problem with using globals but from what I've read it's not recommended as a first solution.
Structure the program using class.
import tkinter
class Prompt:
def button_action(self):
self.my_entry = self.ent.get() #this is the variable I wanna use in another function
def __init__(self, den):
self.lbl = tkinter.Label(den, text="Write Something")
self.ent = tkinter.Entry(den)
self.btn = tkinter.Button(den, text="Get That Something", command=self.button_action)
self.lbl.pack()
self.ent.pack()
self.btn.pack()
den = tkinter.Tk()
den.title("Widget Example")
prompt = Prompt(den)
den.mainloop()
You can access the input using prompt.my_entry later.

Categories