checkLabel = ttk.Label(win,text = " Check Amount ", foreground = "blue")
checkLabel.grid(row = 0 , column = 1)
checkEntry = ttk.Entry(win, textvariable = checkVariable)
checkEntry.grid(row = 1, column = 1, sticky = 'w')
How do I change the defualt entry field from displaying 0?
Use the entry widget's function, .insert() and .delete(). Here is an example.
entry = tk.Entry(root)
entry.insert(END, "Hello") # this will start the entry with "Hello" in it
# you may want to add a delay or something here.
entry.delete(0, END) # this will delete everything inside the entry
entry.insert(END, "WORLD") # and this will insert the word "WORLD" in the entry.
Another way to do this is with the Tkinter StrVar. Here is an example of using the str variable.
entry_var = tk.StrVar()
entry_var.set("Hello")
entry = tk.Entry(root, textvariable=entry_var) # when packing the widget
# it should have the world "Hello" inside.
# here is your delay or you can make a function call.
entry_var.set("World") # this sets the entry widget text to "World"
Set the value of checkVariable to '' (the empty string) before you create the Entry object? The statement to use would be
checkVariable.set('')
But then checkVariable would have to be a StringVar, and you would have to convert the input value to an integer yourself if you wanted the integer value.
Related
Python 3
I want to create a Tkinter label with a handle name that is passed from a function. For example, if the variable name is 'hotdog', I want to create a label that is called 'hotdogLabel', that displays the value of hotdog. I made a function that creates the label, but I dont know how to script the variable input. This does not work
def makeLabel(labelname,width,gridx,gridy,px,py):
name=labelname+'label'
name =Label(window,text=labelname,width=width).grid(row=gridx,column=gridy,padx=px,pady=py)
window = tk.Tk()
makeLabel('FOOBAR',25,1,2,5,5)
window.mainloop()
You didn't assign the value to text you used the old value.
def makeLabel(labelname,width,gridx,gridy,px,py):
name=labelname+'label'
name =Label(window,text=name,width=width).grid(row=gridx,column=gridy,padx=px,pady=py)
window = tk.Tk()
makeLabel('FOOBAR',25,1,2,5,5)
window.mainloop()
The best solution I could think of is to use a dictionary to store a key with the name you want, and the corresponding Label object.
Building on top of your example:
def main():
def makeLabel(labeltext,width,gridx,gridy,px,py):
# dynamically created label name
labelname=labeltext+'label'
# creates Label object and store reference to it in 'label'
label = tk.Label(window, text=labelname,width=width)
# places label on grid
label.grid(row=gridx,column=gridy,padx=px,pady=py)
# returns tuple with label name and Label object
return (labelname, label)
window = tk.Tk()
# initialize dictionary
labelDictionary = {}
# newLblEntry will receive a tuple ('FOOBARlabel', <reference to Label object>)
newLblEntry = makeLabel('FOOBAR',25,1,2,5,5)
# store Label object with the key 'FOOBARlabel'
labelDictionary[newLblEntry[0]] = newLblEntry[1]
window.mainloop()
By doing this, when you need to get the Label created above, simply do Label label = labelDictionary['FOOBARlabel'].
Good link for more on python dictionaries:
http://www.compciv.org/guides/python/fundamentals/dictionaries-overview
I am trying to add items to a list using pythons tkinter as gui. The user can choose the number of values they would like to enter and the program should save those items separately into the same list. Currently The program only appends the last value entered by the user into the list. For example currently if the user chooses to enter 2 values only the second valueis being added to the list. I've posted my exact code below. I'd appreciate if somebody points me in the right direction.
def multiple_chords_num():
global num_chords_screen
num_chords_screen = tk.Toplevel(root)
num_chords_screen.grab_set()
# geometry
center_screen(300, 250, num_chords_screen)
# other screen settings
num_chords_screen.title('Transposition Tool')
num_chords_screen.resizable(width = False, height = False)
tk.Label(num_chords_screen,text = '\n\nHow Many Chords Would you like to Transpose?\n').pack()
num=tk.Entry(num_chords_screen)
num.pack()#pevents from object returning 'None'
tk.Label(num_chords_screen,text = '').pack()
ttk.Button(num_chords_screen, text = 'OK', command = lambda: multiple_chords(num)).pack(ipadx = 10, ipady = 1)
def multiple_chords(num):
global multiple_chords_screen
multiple_chords_screen = tk.Toplevel(root)
multiple_chords_screen.grab_set()
# geometry
center_screen(300, 250, multiple_chords_screen)
# other screen settings
multiple_chords_screen.title('Transposition Tool')
multiple_chords_screen.resizable(width = False, height = False)
num=int(num.get())#obtains num value and turns it into integer
for i in range(0,num):
tk.Label(multiple_chords_screen,text = 'Enter Chord:').pack()
chord=tk.Entry(multiple_chords_screen)
chord.pack()#Prevents 'chord' from returning None
ttk.Button(multiple_chords_screen, text = 'OK', command =lambda : a(chord.get(),num)).pack(ipadx = 10, ipady = 1)
def a(chord):
u_list.append(chord)
print(u_list)
chord can keep only one element. In every loop you assing new Entry to this variable so finally it keeps only last Entry.
You have to keep all Entry on list and send this list to function a.
Function a needs to use for loop to get values from every Entry and append to u_list
More or less:
# list for all entry
all_entry = []
for i in range(0,num):
tk.Label(multiple_chords_screen,text = 'Enter Chord:').pack()
chord=tk.Entry(multiple_chords_screen)
chord.pack()#Prevents 'chord' from returning None
# keep entry on list
all_entry.appen(chord)
# send all_entry to `a`
ttk.Button(multiple_chords_screen, text='OK', command=lambda : a(all_entry, num)).pack(ipadx = 10, ipady = 1)
def a(all_entry):
# get all values
for entry in all_entry:
u_list.append(entry.get())
print(u_list)
I have a dynamically created Tkinter checkbutton widget, which takes in the contents of a list of usernames. I then displayed those names with a checkbox alongside.
What I need to do is obviously collect which usernames have been checked, so I can pass that off to another function to action.
How should I write the variable part of this so it creates a new list of chosen usernames?
What I have thus far:
def delprof_results(users_delprof):
for i in range(len(users_delprof)):
c = Checkbutton(resultsFrame, text=users_delprof[i], variable=users_delprof[i])
c.pack(anchor=W)
def delprof_del():
users_chosen = []
print str(users_delprof[i]).get() # Works up until this point. How to get individual variable with ID.
del_but = Button(resultsFrame, text="Delete", width=7, height=1, command=delprof_del)
del_but.pack(side=LEFT)
Thanks in advance,
Chris.
If you want to reach individual objects, simply keep a reference to the individual objects instead of creating objects while overwriting the same variable with each iteration of a loop like:
for i in range(30):
a = i
How to reach a's state where it was 13? Well, you can't as it's overwritten.
Instead, use collection types. In the example below I used dict:
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
def upon_select(widget):
print("{}'s value is {}.".format(widget['text'], widget.var.get()))
if __name__ == '__main__':
root = tk.Tk()
names = {"Chester", "James", "Mike"}
username_cbs = dict()
for name in names:
username_cbs[name] = tk.Checkbutton(root, text=name,
onvalue=True, offvalue=False)
username_cbs[name].var = tk.BooleanVar()
username_cbs[name]['variable'] = username_cbs[name].var
username_cbs[name]['command'] = lambda w=username_cbs[name]: \
upon_select(w)
username_cbs[name].pack()
tk.mainloop()
You could make a list of values from the checkbuttons:
values = []
for i in range(len(users_delprof)):
v = IntVar()
c = Checkbutton(master, text="Don't show this again", variable=v)
c.var = v
values.append(v)
Now you can check the value by looking in the list values, and getting the value of a checkbutton with v.get().
I have a label that I am setting a random number to.
output.set(randint(1,4))
output = StringVar()
ttk.Label(mainframe, textvariable=output)
I also have an Entry where the user can specify how many random numbers they want to generate.
ttk.Entry(mainframe, textvariable=numberdice, width=5)
What I am trying to do is to get the two values to work together, and have the output label print multiple lines.
I got it to print to the console using a for loop:
for x in range(int(numberdice)):
print(randint(1,4))
But I cant get it to display the same in the GUI...
How to use the print function to display to a GUI
You can create a StringVar that supports write so you can print to it like a file:
import tkinter as tk
class WritableStringVar(tk.StringVar):
def write(self, added_text):
new_text = self.get() + added_text
self.set(new_text)
def clear(self):
self.set("")
Then using print(... , file=textvar) you can add to the string variable exactly the same way as printing to the console:
root = tk.Tk()
textvar = WritableStringVar(root)
label = tk.Label(root, textvariable=textvar)
label.pack()
for i in range(4):
print("hello there", file=textvar)
root.mainloop()
note that because print statements (by default) add a newline at the end there will be an extra blank line at the bottom of the label, if it bugs you it can be worked around by removing the newline and reinserting it next addition:
class WritableStringVar(tk.StringVar):
newline = False
def write(self, added_text):
new_text = self.get()
if self.newline: #add a newline from last write.
new_text += "\n"
self.newline = False
if added_text.endswith("\n"): #remove this newline and remember to add one next write.
added_text = added_text[:-1]
self.newline = True
new_text += added_text
self.set(new_text)
def clear(self):
self.set("")
self.newline = False
Either way you can make use of prints convenient semantics to get text on your GUI.
Is it possible to remove/deactivate variables from a line of code once it has been executed? If not, what are my other options? I wrote a code here to demonstrate what I mean:
from Tkinter import *
root = Tk()
ent_var1 = StringVar()
ent_var2 = StringVar()
ent_var3 = StringVar()
cbtn_var1 = BooleanVar()
cbtn_var2 = BooleanVar()
cbtn_var3 = BooleanVar()
ent1 = Entry(textvariable=ent_var1).pack()
ent2 = Entry(textvariable=ent_var2).pack()
ent3 = Entry(textvariable=ent_var3).pack()
cbtn1 = Checkbutton(text=1, variable=cbtn_var1).pack(side = LEFT)
cbtn2 = Checkbutton(text=2, variable=cbtn_var2).pack(side = LEFT)
cbtn3 = Checkbutton(text=3, variable=cbtn_var3).pack(side = LEFT)
# prints what was written in entires
def set_variables():
lbl1 = ent_var1.get()
lbl2 = ent_var2.get()
lbl3 = ent_var3.get()
print lbl1, lbl2, lbl3
return
# calls set_variables
btn1 = Button(root, text="Done!", command=set_variables).pack()
root.mainloop()
When you fill the entries and press "Done!", what was written is printed. But how do I make it so that when I press the checkboxes, the entry linked to it will not be printed the next the I press "Done!"? The checkbox with the text "1" should be linked with the first entry, and so on.
I came up with this:
def should_print():
global lbl_print
if cbtn1:
lbl_print += lbl1
if cbtn2:
lbl_print += lbl2
if cbtn3:
lbl_print += lbl3
But it would only print the values of my variables at that very moment, not the variables themselves (meaning I'd have to run this code every time a variable changes).
Thank you!
Your question is very hard to understand. I think what you want is for set_variables to only print the variables associated with a checked checkbox. If so, does the following do what you want?
def set_variables():
to_print = []
if cbtn_var1.get():
to_print.append(ent_var1.get())
if cbtn_var2.get():
to_print.append(ent_var2.get())
if cbtn_var3.get():
to_print.append(ent_var3.get())
print " ".join(to_print)
return
There are other ways to accomplish the same thing, but I'm guessing your main goal is to decide what to print based on which checkbuttons are checked. This does that, albeit in a rather ham-fisted manner.
Why don't you simply check in your set_variables function if each button is pressed? For example:
def set_variables():
if not cbtn_var1.get():
print ent_var1.get(),
if not cbtn_var2.get():
print ent_var2.get(),
if not cbtn_var3.get():
print ent_var3.get(),
print
The commas at the end of each print statement will cause it to not print a newline, which is taken care of by the print at the end. Also, this will make so that if the box is checked, the value they entered won't print. If you want it to print only if the box is checked, then remove the nots.
If you refactor your code a little bit, you can do the same thing with one line. First, add this line:
cbtn_var1 = BooleanVar()
cbtn_var2 = BooleanVar()
cbtn_var3 = BooleanVar()
buttonsAndValues = [(cbtn_var1,ent_var1), (cbtn_var2,ent_var2), (cbtn_var3,ent_var3)]
With the variables in a list, you can use a list comprehension in some Python magic:
def set_variables():
print ' '.join(value.get() for checked, value in buttonsAndValues if checked.get())
If you haven't seen list comprehensions before, I'd suggest you read up about them - they can be very handy.