I get the user entry as a StringVar from an Entry box but would like to convert it to uppercase.
I then use the variable in another routine. I have been unable to find the syntax to simply convert 'c6h12' to 'C6H12' when its in a StringVar.
Any help appreciated.
The following snippet does the trick, simply using the StringVar get() method to get the old value, and set() method to update the value after calling upper()
from tkinter import *
root = Tk()
sv = StringVar(value="c6h12")
sv.set(sv.get().upper())
root.mainloop()
Related
I'm writing a GUI application with tkinter and I have different classes that represent different pages of my application. I'm trying to call a variable from one class to another, so I used the repr() function to gain some insight into how to call that object from one class to antother.
I called print(repr(listbox))
my listbox is within a class named SelectionPage and is defined as listbox = tk.Listbox(self)
the representation printed as <tkinter.Listbox object .!selectionpage.!listbox>
I'm new to python and I'm confused as to what these exclamation marks mean. Is this even a good way to debugg?? Sorry if this is a duplicate question, I'm really confused and I couldn't find the answer elsewhere
What do exclamation marks mean in the representation of an object
They don't mean anything. Tkinter developers simply chose to give all of their autogenerated internal widget names a leading exclamation point.
Tkinter is just a python wrapper around a tcl/tk interpreter. In tcl/tk, a widget is represented as a hierarchy of widgets. For example, the root widget is .. A frame in the root might be named .frame. A listbox in that frame might be named .frame.lb. Tcl is very broad in what it will accept - essentially, a widget name can be any character other than "." so using an exclamation point is legal, though uncommon in the tcl/tk world.
When you create a Tkinter widget by instantiating one of its classes, tkinter must create a valid widget name to pass to the tcl interpreter in order to create the actual widget. In older versions of Tkinter it used unique numbers (eg: '.4368693152.4368765368'). In python3, tkinter chose to use more human-friendly names prefixed with an exclamation point.
As far as I know, the exclamation point has no special meaning, though I suppose it might be useful in determining whether a widget name was created by tkinter or through some other means.
I'm trying to call a variable from one class to another, so I used the repr() function to gain some insight into how to call that object from one class to antother.
There are almost certainly better ways to do that than to use the internal name of the widget. However, if you know the internal name of the widget (eg: ".!selectionpage.!listbox") and insist on doing it this way, you can convert the string name to the tkinter widget instance with the universal widget method nametowidget.
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root)
listbox = tk.Listbox(frame)
listbox_name = str(listbox)
lb = root.nametowidget(listbox_name)
assert lb is listbox
By the way, you can give widgets a name if you don't like the autogenerated name. This works for all widgets except the root widget.
import tkinter as tk
root = tk.Tk()
frame = tk.Frame(root, name="my_frame")
listbox = tk.Listbox(frame, name="my_listbox")
assert str(listbox) == ".my_frame.my_listbox"
I have made a variable called 'localtime2' within my def in the code and then have a label which says 'textvariable=localtime2.' the problem is that it does not display the information about the variable.
localtime2 = time.asctime(time.localtime(time.time()))
tk.Label(roots, font=('arial', 16, 'bold'), textvariable=localtime2, bd=16, anchor="w").grid(row=2, column=0)
This is all I have in the code about this variable and it is not coming up with any error in the terminal. It just doesnt show at all.
Edit: The solution to the original post was using text=localtime2.get() instead of textvariable=localtime2 in the label widget (for some strange reason). However, my original answer is still correct as tkinter variables should be used and so I will keep it up.
You must use tkinter variables in tkinter widgets and not normal python variables. Tkinter variables are slightly different to normal variables and must first be defined as a specific data type. For example, a variable which contains a string must be first created like so:
string_variable = tk.StringVar()
likewise a boolean would be created like so:
boolean_variable = tk.BooleanVar()
Read here for more information on tkinter variables.
These variables are in fact classes so in order to set them use must call the .set() method. Therefore to set a tkinter String variable to "a string" you would use the following code:
string_variable = tk.StringVar() # Create the variable
string_variable.set("a string") # Set the value of the variable
Thus to fix your code you need to make localtime2 a tkinter variable and set it to the time using the .set() method.
Example:
localtime2 = tk.StringVar() # Create the localtime2 string variable
localtime2.set(time.asctime(time.localtime(time.time()))) # Set the variable
tk.Label(roots, font=('arial', 16, 'bold'), textvariable=localtime2, bd=16, anchor="w").grid(row=2, column=0)
Whenever there is a change in a tkinter variable, the update is automatically reflected everywhere. Because of this property you cannot use a normal python variable here.
Try using StringVar() and then setting the variable content using set()
my code looks like this
root = Tk()
a = IntVar(root)
later in my code i cannot access 'a' but i can access 'root'
I tried
root.getvar('a')
root.children
root.client()
root.slaves()
root.getint(0)
and none of them is or contains 'a'
and I need value from 'a'
how can I get it
You cannot get a tkinter variable given only the root window, or the master of a widget. At least, not without a lot of work. Tkinter simply doesn't keep track of these variables for you.
To gain access to the variable, you must do the same with it as you do with any other python variable or object: you need to make it global, or a class or instance variable, or you need to pass it to the function that needs access.
I'm trying to automatically clear all Entry widgets in a parent widget.
import Tkinter
import re
root=Tkinter.Tk()
E1=Tkinter.Entry(root)
E1.pack()
E2=Tkinter.Entry(root)
E2.pack()
L1=Tkinter.Label(root,text='Label1')
L1.pack()
I'm running into 3 problems
While I can find out the children widget type, I can't seem to be able to use it in a pattern match. Printing out the wlist[0] below is different from the shell output?
Eg:
>> wlist=root.winfo_children()
>> wlist
[<Tkinter.Entry instance at 0x00000000151911C8>,
<Tkinter.Entry instance at 0x00000000151BAD88>,
<Tkinter.Label instance at 0x00000000151B29C8>]
>> wlist[0] # shell output
<Tkinter.Entry instance at 0x00000000151911C8>
>> print wlist[0] # print output here is different vs shell output above
.353964488L
I think due to the differences between the print output & shell output above, my pattern match can't work?
Eg
>> re.search(r'Entry',wlist[0])
<< No output >>
Assuming one is able to determine via pattern match that a child widget is indeed an Entry widget, how would you get the widget object itself to perform a delete method call?
Eg:
## Assuming I have a function to to clear the entry
## How would I pass the object from the pattern match in #2 to this function?
def clear_entry(objEntry):
objEntry.delete(0,Tkinter.END)
The items returned from winfo_children() is a list of widgets. Tkinter widgets have a method to tell you the underlying widget class: winfo_class.
>>> wlist[0].winfo_class()
'Entry'
You can also simply compare the object type, like you can with any other python object:
>>> isinstance(wlist[0], Tkinter.Entry)
True
Since the result of winfo_children is a list of widgets, you can iterate over them and clear out all of the entry widgets like this:
for widget in root.winfo_children():
if isinstance(widget, Tkinter.Entry):
widget.delete(0, "end")
Normally you store them in a list or some container.
entry_list=[E1, E2]
def clear_entry():
for id in entry_list:
id.delete(0,Tkinter.END)
You can check typu using
if type(wlist[0]) == Tkinter.Entry: # True/False
or better
if isinstance(wlist[0], Tkinter.Entry): # True/False
wlist[0] is object so you can do
wlist[0].delete(0,Tkinter.END)
and
clear_entry(wlist[0])
When you try to print object it use str() to convert object to string
print str(wlist[0])
.353964488L
shell use repr() to convert object to string
print repr(wlist[0])
<Tkinter.Entry instance at 0x00000000151911C8>
Now, I know that you can check to see if a window exists by:
x.winfo_exists()
which returns a Boolean. More exactly, I need to check the existence of my buttons, labels, list boxes, sliders etc. Then what?
winfo_exists returns 1 unless you have destroyed the widget, in which case it returns 0. This method can be called on any widget class, not only the Tk root or Toplevels. Alternatively, you can get all the children of a widget with winfo_children:
>>> import Tkinter as tk
>>> root = tk.Tk()
>>> label = tk.Label(root, text="Hello, world")
>>> label.winfo_exists()
1
>>> root.winfo_children()
[<Tkinter.Label instance at 0x0000000002ADC1C8>]
>>> label.destroy()
>>> label.winfo_exists()
0
>>> root.winfo_children()
[]
You can also print the type i.e.. type(label). This can be helpful to provide not only existence, but also find if anything is coming up 'NoneType' without an error. The type() will tell you if you have an instance, or other type that can provide valuable clues as to how close the program is performing or returning items to what you think you are asking! The object.winfo_exists() and object.winfo_children is specific, and will throw an error if the object is not a type 'instance'.