Any ideas why the leftresult_label label does not update? The function seems to work but the label does not update. I have looked everywhere and can't find an answer. The 'left' value gets set but the label does not change.
from tkinter import *
root = Tk(className="Page Calculator")
read = IntVar()
total = IntVar()
left = IntVar()
read.set(1)
total.set(1)
left.set(1)
read_label = Label(root,text="Pages Read:")
read_label.grid(column=1, row=1)
total_label = Label(root,text="Total Pages:")
total_label.grid(column=1, row=2)
read_entry = Entry(root,textvariable=read)
read_entry.grid(column=2, row=1)
total_entry = Entry(root,textvariable=total)
total_entry.grid(column=2, row=2)
def func1():
left.set(total.get() - read.get())
print(left.get())
calculate_button = Button(root,text="Calculate",command= func1)
calculate_button.grid(column=2, row=3)
percenet_label = Label(root,text="Percent Finished:")
percenet_label.grid(column=1, row=4)
left_label = Label(root,text="Pages Left:")
left_label.grid(column=1, row=5)
percenetresult_label = Label(root,text=left.get())
percenetresult_label.grid(column=2, row=4)
leftresult_label = Label(root,text="")
leftresult_label.grid(column=2, row=5)
root.mainloop()
To make the function do the job, you'd rather have your label:
leftresult_label = Label(root, textvariable=left)
Once it's tkinter class variable, tkinter takes care about when you change the value. Once you click the button,
def func1():
left.set(total.get() - read.get())
percent.set(int(read.get()*100/total.get()))
left and percent values, which are instances of tkinter.IntVar() class have immidiate effect on widgets (labels in this case) where those values are set as textvariable, just as you have it at Entry widgets.
Here is full code:
from tkinter import *
root = Tk(className="Page Calculator")
read = IntVar()
total = IntVar()
left = IntVar()
percent = IntVar()
read.set(1)
total.set(1)
left.set(1)
percent.set(1)
def func1():
left.set(total.get() - read.get())
percent.set(int(read.get()*100/total.get()))
read_label = Label(root,text="Pages Read:")
read_label.grid(column=1, row=1)
read_entry = Entry(root,textvariable=read)
read_entry.grid(column=2, row=1)
total_label = Label(root,text="Total Pages:")
total_label.grid(column=1, row=2)
total_entry = Entry(root,textvariable=total)
total_entry.grid(column=2, row=2)
calculate_button = Button(root,text="Calculate",command= func1)
calculate_button.grid(column=2, row=3)
percenet_label = Label(root,text="Percent Finished:")
percenet_label.grid(column=1, row=4)
left_label = Label(root,text="Pages Left:")
left_label.grid(column=1, row=5)
percenetresult_label = Label(root,textvariable=percent)
percenetresult_label.grid(column=2, row=4)
leftresult_label = Label(root,textvariable=left)
leftresult_label.grid(column=2, row=5)
root.mainloop()
code including progress bar. update_idletasks() used to keep label and progress bar running.
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('Counter Test')
root.iconbitmap('IT.ico')
root.geometry("800x400")
def missing():
while i < 100:
progress1['value'] = i
label1.config(text=progress1['value'])
root.update_idletasks()
i += 1
progress1 = ttk.Progressbar(root, orient=HORIZONTAL, length=250, mode='determinate')
progress1.pack(pady=15)
label1 = Label(root, text="")
label1.pack(pady=15)
button_1 = Button(root, text="Missing", command=missing)
button_1.pack(pady=15)
button_q = Button(root, text="Quit", command=root.destroy)
button_q.pack(pady=15)
root.mainloop()
so to update controls immediately, like updating labels and TreeView elements this code worked for me.
window = tk.Tk()
window.update_idletasks()
Related
I'm new to coding and I'm trying to grab an input from an entry using tkinter in python. In theory, I should click the 'upload' button, then the code will get the entry and print it for me, but this isn't working. This is my code.
from tkinter import *
root = Tk()
frame = Frame(root)
frame.pack()
def cancel():
quit()
def upload():
Entry.get()
print(Entry)
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
whitebutton = Entry(frame, fg="black")
whitebutton.pack( side = TOP)
redbutton = Button(frame, text="Cancel", fg="red", command = cancel)
redbutton.pack( side = LEFT)
bluebutton = Button(frame, text="Upload URL", fg="blue", command = upload)
bluebutton.pack( side = RIGHT )
root.mainloop()
Does anyone know what's going wrong here?
Thanks, Kieran.
Entry is a class in __init__ file in tkinter folder.
Instead of this:
Entry.get()
print(Entry)
This is what you need
var=whitebutton.get()
print(var)
First of all, it is better to use Tkinter variables rather than normal python variables. Here you need to use StringVar() to set and get an user input from entry. So the complete code -
from tkinter import *
root = Tk()
var = StringVar()
frame = Frame(root)
frame.pack()
def cancel():
quit()
def upload():
print(var.get())
bottomframe = Frame(root)
bottomframe.pack( side = BOTTOM )
whitebutton = Entry(frame,textvariable=var ,fg="black")
whitebutton.pack( side = TOP)
redbutton = Button(frame, text="Cancel", fg="red", command = cancel)
redbutton.pack( side = LEFT)
bluebutton = Button(frame, text="Upload URL", fg="blue", command = upload)
bluebutton.pack( side = RIGHT )
root.mainloop()
For more info - this and this
put root var before root.mainloop()
and make app var and put into "Application(root)"
then change ""root".mainloop()" to "app.mainlop()"
import tkinter as tk
// your code
root = tk.Tk()
app = Application(root)
app.mainloop()
I am trying to modify my flashcard python script. It works fine, but what I am triying to do is to modify the random function so that a single question (and its answer) it is not chosen twice. The script should not continue picking questions after the list is completed. I would also need to add a button that let me brwose back to previuos selections.
Any suggestions?
from tkinter import *
from tkinter import ttk
from random import randint
root = Tk()
root.title('Domande')
root.geometry("850x400")
root.resizable(True, True)
words = [
(("Stadio Olimpico"), ("ROMA")),
(("Stadio Artemio Franchi"), ("FIORENTINA")),
(("Stadio Armando Picchi"), ("LIVORNO")),
(("Stadio Luigi Ferraris"), ("SAMPDORIA"))
(("Stadio Arechi"), ("SALERNITANA"))
]
# get a count of our wods list
count = len(words)
def next():
global hinter, hint_count
#Clear screen
answer_label.config(text="")
label.config(text="")
hint_label.config(text="")
#Reset Hint stuff
hinter = ""
hint_count = 0
#Create random selection
global random_domande
random_domande = randint(0, count-1)
#Update label with Domande
domande.config(text=words[random_domande][0])
#Keep track of the hint
hinter = ""
hint_count = 0
def hint():
global hint_count
global hinter
if hint_count < len(words[random_domande][1]):
hinter = hinter + words[random_domande][1][hint_count]
hint_label.config(text=hinter)
hint_count +=1
#Define function to hide the widget
def hide_widget(widget):
widget.pack_forget()
widget.config(text=words[random_domande][1])
#Define a function to show the widget
def show_widget(widget):
widget.pack()
widget.config(text=words[random_domande][1])
#Labels
domande = Label(root, text="", font=("Times", 14))
domande.pack(side=TOP)
#Create an Label Widget
label = Label(root, text="", font=("Times", 14))
label.pack()
#Create Buttons
button_frame = Frame(root)
button_frame.pack()
hint_button = Button(button_frame, text="Hint", command=hint)
hint_button.pack()
button_show = Button(root, text= "Show", command= lambda:show_widget(label))
button_show.pack()
#Create a button Widget
button_hide = Button(root, text= "Hide", command=lambda:hide_widget(label))
button_hide.pack()
next_button = Button(button_frame, text="Next", command=next)
next_button.pack()
#Create Hint Label
hint_label = Label(root, text="")
hint_label.pack()
answer_label = Label(root, text="", font=("Times", 14))
answer_label.pack(side=BOTTOM)
#Run next function when the program starts
next()
root.mainloop()
I have only been programming 3 months so any advice on improvement to my code is appreciated even if it inst related to my specific question.
Its a simple small project with tkinter. Two fields to enter your first and last name then you hit the swap button and it will swap what ever you put in the name fields.
Problem is I dont want to use globals and I cant seem to figure it out I know its probably something easy and I did spend time trying to figure it out.
If you have any improvements to the code let me know.
from tkinter import *
### I dont Want Globals but cant figure out another method for doing this
### Hope some one can help me with this part
evar = ""
evar1 = ""
def mainWindow():
root = Tk()
root.title("Swap Names")
root.geometry("400x150+100+250")
return root
def createVar():
global evar
global evar1
evar = StringVar()
evar1 = StringVar()
def firstNameFrame(root):
frame1 = Frame(root)
frame1.pack(side=TOP, padx=2, pady=2)
label = Label(frame1, text="First Name:")
label.pack(side=LEFT, padx=2, pady=2)
entry = Entry(frame1, textvariable = evar)
entry.pack(side=LEFT, pady = 2)
def lastNameFrame(root):
frame2 = Frame(root)
frame2.pack(side=TOP, padx=2, pady=2)
label = Label(frame2, text="Last Name:")
label.pack(side=LEFT, padx=1, pady=1)
entry = Entry(frame2, textvariable = evar1)
entry.pack(side=LEFT, pady = 5)
def swapFrame(root):
frame3 = Frame(root)
frame3.pack(side=TOP, padx=10, pady = 10)
swapButton = Button(frame3, text="Swap",command = swap)
swapButton.pack(side=LEFT, padx =5, pady=5)
### I would like to some how use swap with out using a global
def swap():
b=evar.get()
evar.set(evar1.get())
evar1.set(b)
def main():
root = mainWindow()
createVar()
firstNameFrame(root)
lastNameFrame(root)
swapFrame(root)
root.mainloop()
main()
One of the solutions can be wrapping all the code related to the initialization and working with Tk in a separate class, so instead of global variables, we will use the class instance variables:
from tkinter import *
class Gui(object):
def __init__(self):
self.root = Gui._init_main_window()
self.first_name_var = StringVar()
self.last_name_var = StringVar()
self._init_first_name_frame()
self._init_last_name_frame()
self._init_swap_frame()
#staticmethod
def _init_main_window():
root = Tk()
root.title("Swap Names")
root.geometry("400x150+100+250")
return root
def _init_first_name_frame(self):
frame1 = Frame(self.root)
frame1.pack(side=TOP, padx=2, pady=2)
label = Label(frame1, text="First Name:")
label.pack(side=LEFT, padx=2, pady=2)
entry = Entry(frame1, textvariable=self.first_name_var)
entry.pack(side=LEFT, pady=2)
def _init_last_name_frame(self):
frame2 = Frame(self.root)
frame2.pack(side=TOP, padx=2, pady=2)
label = Label(frame2, text="Last Name:")
label.pack(side=LEFT, padx=1, pady=1)
entry = Entry(frame2, textvariable=self.last_name_var)
entry.pack(side=LEFT, pady=5)
def _init_swap_frame(self):
frame3 = Frame(self.root)
frame3.pack(side=TOP, padx=10, pady=10)
swap_button = Button(frame3, text="Swap", command=self._swap)
swap_button.pack(side=LEFT, padx=5, pady=5)
def _swap(self):
tmp = self.first_name_var.get()
self.first_name_var.set(self.last_name_var.get())
self.last_name_var.set(tmp)
def mainloop(self):
return self.root.mainloop()
def main():
gui = Gui()
gui.mainloop()
if __name__ == '__main__':
main()
A small comment to the code above: adding a prefix __ to variables or methods allows you to hide access to them directly by name outside the class using the name mangling.
UPD: According to #Coal comment, changed the double underscore prefixes to single underscore, as there is no need to use a name mangling.
This is assuming that when you say you don't want to use global, that you also mean that you don't want to use self:
from tkinter import Tk, Button, Entry
def swap(fn, ln):
# Get the contents of the two fields.
first = fn.get()
last = ln.get()
# Clear the contents of both fields.
first_name.delete(0, 'end')
last_name.delete(0, 'end')
# Set each field to the previous content of the other field.
first_name.insert(0, last)
last_name.insert(0, first)
root = Tk()
first_name = Entry(root)
last_name = Entry(root)
first_name.insert(0, "Enter first name")
last_name.insert(0, "Enter last name")
first_name.pack()
last_name.pack()
swap_button = Button(root, text="SWAP", command=lambda:swap(first_name, last_name))
swap_button.pack()
root.mainloop()
I got this problem. when I write secretframe() I get a empty box any ideas to fix this? Also how can I put a little space between the 2 frames.
I'm new to tkinter and any tips is gladly appreciated.
import tkinter as tk
import time
import math
##----------Functions
root = tk.Tk()
def Pi():
pi = math.pi
x = list(str(pi))
map(int,x)
print(math.pi)
def Unfinished():
print("This Button is not finished")
def secretframe(frame):
secrett = tk.Toplevel()
sframe = tk.Frame(secrett, height="300", width="300", bg="PeachPuff")
sLabel = tk.Label(sframe, text="Secret")
sframe.grid
sLabel.grid
##Defining
##Frames
frame = tk.Frame(root, height="300", width="300", bg="Black")
Mframe = tk.Frame(root, height="300", width="300", bg="White")
##WIdgets
Label = tk.Label(frame, text="R1p windows", bg="Black", fg="White")
Label2 = tk.Label(Mframe, text="Math magic", bg="White", fg="Black")
Knapp = tk.Button(frame, text="ok(ADMIN)", fg="White", bg="Black", font="monospace")
PIKnapp = tk.Button(Mframe, text="Pi(WIP)(UNFINISHED)", bg="White", fg="Black", font="Times")
##Config and bindings
Knapp.config(command=Unfinished)
PIKnapp.config(command=Pi)
##Packing
## Frame 1
Label.grid()
frame.grid()
Knapp.grid()
## Frame 2
Label2.grid()
Mframe.grid()
PIKnapp.grid()
You've forgotten the brackets. Try:
sframe.grid ()
sLabel.grid ()
First time here so forgive me as this is my FIRST attempt at making a silly GUI game (if you want to call it that). I'm trying to get the user to click a button and the image of their selection pops up. I can't seem to figure out how to get the image to pop up though.
Image does show if I run it separately.
My code:
from Tkinter import *
root = Tk()
class PokemonClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text="Welcome! Pick your Pokemon!",
bg="Black", fg="White")
self.WelcomeLabel.pack(fill=X)
self.CharButton = Button(root, text="Charmander", bg="RED", fg="White",
command=self.CharClick)
self.CharButton.pack(side=LEFT, fill=X)
self.SquirtButton = Button(root, text="Squirtle", bg="Blue", fg="White")
self.SquirtButton.pack(side=LEFT, fill=X)
self.BulbButton = Button(root, text="Bulbasaur", bg="Dark Green",
fg="White")
self.BulbButton.pack(side=LEFT, fill=X)
def CharClick(self):
print "You like Charmander!"
global CharSwitch
CharSwitch = 'Yes'
CharSwitch = 'No'
if CharSwitch == 'Yes':
CharPhoto = PhotoImage(file="Charmander.gif")
ChLabel = Label(root, image=CharPhoto)
ChLabel.pack()
k = PokemonClass(root)
root.mainloop()
This works, but the actual image no longer shows, if I keep the PhotoImage OUT of the class it will print but I want to have it print IF they click the specific button:
from Tkinter import *
root = Tk()
class PokemonClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text = "Welcome! Pick your Pokemon!", bg = "Black", fg = "White")
self.WelcomeLabel.pack(fill = X)
self.CharButton = Button(root, text = "Charmander", bg = "RED", fg = "White", command = CharClick)
self.CharButton.pack(side = LEFT, fill = X)
self.SquirtButton = Button(root, text = "Squirtle", bg = "Blue", fg = "White")
self.SquirtButton.pack(side = LEFT, fill = X)
self.BulbButton = Button(root, text = "Bulbasaur", bg = "Dark Green", fg = "White")
self.BulbButton.pack(side = LEFT, fill = X)
def CharClick():
print "You like Charmander!"
CharPhoto = PhotoImage(file = "Charmander.gif")
ChLabel = Label(root, image = CharPhoto)
ChLabel.pack()
k = PokemonClass(root)
root.mainloop()
You need to maintain a reference to your PhotoImage object. Unfortunately there is an inconsistency in tkinter in that attaching a Button to a parent widget increments the reference count, but adding an image to a widget does not increment the reference count. As a consequence at the moment the CharPhoto variable goes out of scope at the end of the function CharClick, the number of reference to the PhotoImage falls to zero and the object is made available for garbage collection.
If you keep a reference to the image somewhere, it will appear. When you kept it globally it remained in scope for the entire script and hence appeared.
You can keep a reference to it in the PokemonClass object or in the Label widget.
Below is the later of those options
from Tkinter import *
root = Tk()
class PokemonClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text="Welcome! Pick your Pokemon!",
bg="Black", fg="White")
self.WelcomeLabel.pack(fill=X)
self.CharButton = Button(root, text="Charmander", bg="RED", fg="White",
command=self.CharClick)
self.CharButton.pack(side=LEFT, fill=X)
self.SquirtButton = Button(root, text="Squirtle", bg="Blue", fg="White")
self.SquirtButton.pack(side=LEFT, fill=X)
self.BulbButton = Button(root, text="Bulbasaur", bg="Dark Green",
fg="White")
self.BulbButton.pack(side=LEFT, fill=X)
def CharClick(self):
print "You like Charmander!"
global CharSwitch
CharSwitch = 'Yes'
CharPhoto = PhotoImage(file="Charmander.gif")
ChLabel = Label(root, image=CharPhoto)
ChLabel.img = CharPhoto
ChLabel.pack()
CharSwitch = 'No'
k = PokemonClass(root)
root.mainloop()
The solution which helped me is just simply declaring all the image variables on the next line after 'root = Tk()'. Doing so won't spoil your code or anything.