How can I update the photo within a button using radio buttons? - python

I'm currently trying to learn how to build GUIs with tkinter, and I've run into a problem with my test app.
I have a button that displays an image on it instead of text, and I also have a set of radio buttons that I want to control which image is shown on the regular button. Currently the radio buttons don't seem to be updating my photofilepath StringVar as the button always has the default photo, regardless of selected radio button. Here is my (Simplified) code:
root = Tk() # Set up
root.title("Test GUI")
gui.grid(column=0, row=0, sticky=(N, W, E, S))
photofilepath = StringVar() # Set default photo
photofilepath.set("C:/Users/Ben/Pictures/Default photo.png")
photo = PhotoImage(file=photofilepath.get())
CalcButton = ttk.Button(gui, image=photo)
CalcButton.grid(column=3, row=2, columnspan=1)
# Set button photo
Photo1Rbutton = ttk.Radiobutton(gui, text="Photo 1", variable=photofilepath,
value='C:/Users/Ben/Pictures/Photo 1.png')
Photo1Rbutton.grid(column=4, row=2, sticky=S)
Photo2Rbutton = ttk.Radiobutton(gui, text="Photo 2", variable=photofilepath,
value='C:/Users/Ben/Pictures/Photo 2.png')
Photo2Rbutton.grid(column=4, row=3)
root.mainloop()
Thanks in advance for any help.

You can use command= in Radiobutton to assign function which will load new image and put them in label.
Working example (you have to only set paths)
import tkinter as tk
from tkinter import ttk
# to easily change example
DEFAULT = "C:/Users/Ben/Pictures/Default photo.png"
PHOTO_1 = "C:/Users/Ben/Pictures/Photo 1.png"
PHOTO_2 = "C:/Users/Ben/Pictures/Photo 2.png"
def change_image():
print(photo_filepath.get())
photo = tk.PhotoImage(file=photo_filepath.get())
calc_button['image'] = photo
calc_button.image = photo # solution for garbage-collector problem. you have to assign PhotoImage object to global variable or class variable
# - or -
photo['file'] = photo_filepath.get()
calc_button['image'] = photo
root = tk.Tk() # Set up
root.title("Test GUI")
photo_filepath = tk.StringVar() # Set default photo
photo_filepath.set(DEFAULT)
photo = tk.PhotoImage(file=photo_filepath.get())
calc_button = ttk.Button(root, image=photo)
calc_button.grid(column=3, row=2, columnspan=1)
photo1_radiobutton = ttk.Radiobutton(root, text="Photo 1", variable=photo_filepath,
value=PHOTO_1, command=change_image)
photo1_radiobutton.grid(column=4, row=2, sticky=tk.S)
photo2_radiobutton = ttk.Radiobutton(root, text="Photo 2", variable=photo_filepath,
value=PHOTO_2, command=change_image)
photo2_radiobutton.grid(column=4, row=3)
root.mainloop()

Related

How to update and show in real time on label 2 what user write in ENTRY label1?

If i have this ENTRY label1 on pos1, how can i update and show "in real time" the text i write on other label 2 in position2?
label1 = Entry(root, font=('aria label', 15), fg='black')
label1.insert(0, 'enter your text here')
label1_window = my_canvas.create_window(10, 40, window=entry)
label2 = how to update and show in real time what user write on label1
If the entry and label use the same StringVar For the textvariable option, the label will automatically show whatever is in the entry. This will happen no matter whether the entry is typed in, or you programmatically modify the entry.
import tkinter as tk
root = tk.Tk()
var = tk.StringVar()
canvas = tk.Canvas(root, width=400, height=200, background="bisque")
entry = tk.Entry(root, textvariable=var)
label = tk.Label(root, textvariable=var)
canvas.pack(side="top", fill="both", expand=True)
label.pack(side="bottom", fill="x")
canvas.create_window(10, 40, window=entry, anchor="w")
root.mainloop()
Issues in your attempt: The variable names are not clear as you are creating an Entry component and then assigning it to a variable named label1 which can be confusing.
Hints: You can do one of the following to tie the label to the entry so that changing the text in the entry causes the text in the label to change:
Use a shared variable
Implement a suitable callback function. You can, for example, update the label each time the KeyRelease event occurs.
Solution 1 - Shared variable: Below is a sample solution using a shared variable:
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.title('Example')
root.geometry("300x200+10+10")
user_var = StringVar(value='Enter text here')
user_entry = Entry(root, textvariable=user_var, font=('aria label', 15), fg='black')
user_entry.pack()
echo_label = Label(root, textvariable=user_var)
echo_label.pack()
root.mainloop()
Solution 2 - Callback function: Below is a sample solution using a suitable callback function. This is useful if you wish to do something more:
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.title('Example')
root.geometry("300x200+10+10")
def user_entry_changed(e):
echo_label.config({'text': user_entry.get()})
user_entry = Entry(root, font=('aria label', 15), fg='black')
user_entry.insert(0, 'Enter your text here')
user_entry.bind("<KeyRelease>", user_entry_changed)
user_entry.pack()
echo_label = Label(root, text='<Will echo here>')
echo_label.pack()
root.mainloop()
Output: Here is the resulting output after entering 'abc' in the entry field:

Add an image on a 'price button' tkinter

A very simple question again. Once again, I have done my research on all websites but only one article kind of helps me.
Here is the article: How do I create a button in Python Tkinter to increase integer variable by 1 and display that variable?
And this is the code I am interested in (from the article above):
import tkinter
import sys
root = tkinter.Tk()
root.geometry("200x200")
root.title("His Button Increaser")
counter = tkinter.IntVar()
def onClick(event=None):
counter.set(counter.get() + 1)
tkinter.Label(root, textvariable=counter).pack()
tkinter.Button(root, text="Increase", command=onClick, fg="dark green", bg =
"white").pack()
root.mainloop()
Basically, I want to add an image to the button and remove the text on that button, so the user sees a picture, and when they click on the button, it displays the price at the top.
The part of my code I want to implement is:
PhotoImage(file = "imageofcar".png")
Thanks :)
To display an image on the button, you just have to pass the associated PhotoImage object to the Button through the parameter named image. Here is the solution:
import tkinter
root = tkinter.Tk()
root.geometry("200x200")
root.title("His Button Increaser")
counter = tkinter.IntVar()
def onClick(event=None):
counter.set(counter.get() + 1)
tkinter.Label(root, textvariable=counter).pack()
photo = tkinter.PhotoImage(file='imageofcar.png')
tkinter.Button(root, image=photo, command=onClick, fg="dark green", bg = "white").pack()
root.mainloop()
You can do this as following: First you create a PhotoImage object in which you pass the image you want to load as parameter, then you configure your button to accept this image at the specified size and finally you pack the button with pack():
from tkinter import *
import sys
root = Tk()
root.geometry("200x200")
root.title("His Button Increaser")
counter = IntVar()
def onClick(event=None):
counter.set(counter.get() + 1)
label = Label(root, textvariable=counter).pack()
button = Button(root, text="Increase", command=onClick, fg="dark green", bg = "white")
photo = PhotoImage(file = "imageofcar.png")
button.config(image=photo,width="100",height="100")
button.pack()
root.mainloop()
You can add an image to a button like this:
image = Image.open("imageofcar.jpg")
photo = ImageTk.PhotoImage(image)
b.config(image=photo)
where b is a reference to the button object.
It's usually a bad idea to create a Tk object and "pack" it in one line, because the pack function returns None.
These changes added to your code results in this:
import tkinter
import sys
from PIL import Image, ImageTk
root = tkinter.Tk()
root.geometry("200x200")
root.title("His Button Increaser")
counter = tkinter.IntVar()
def onClick(event=None):
counter.set(counter.get() + 1)
tkinter.Label(root, textvariable=counter).pack()
b = tkinter.Button(root, text="Increase", command=onClick, fg="dark green", bg =
"white")
b.pack()
image = Image.open("imageofcar.jpg")
photo = ImageTk.PhotoImage(image)
b.config(image=photo)
root.mainloop()

python 3 Tkinter ComboBox don't get value

I am trying to get the value of from a combobox in tkinter using python 3.6, i been looking to many tutorials but i don't see the problem yet.
every time i press the button don't show anything.
but also there is not errors.
so to clarify ... I am trying to get the value of the tk.combobox when i press ttk.Button.
thank you in advance for any ideas or comments.
this is what i have so far.
import tkinter as tk
from tkinter import ttk
def combo_box_updater():
total_location = ['linden', 'mineola', 'brooklyn']
return total_location
def start_analisys(event=None):
site = jobsite_name.get()
print(site)
# this is part of a definition that automatically will update the names in later versions
job_site = combo_box_updater()
# basic gui setup
unified = tk.Toplevel()
unified.title('Unified 1 Week Timesheet')
unified.configure(background="#00012f")
unified.geometry("650x200")
unified.resizable(width=False, height=False)
entry_width = 30
# basic frame
frame1 = tk.Frame(unified)
frame1.grid(row=0, column=0, sticky='w')
# combo box in the fourth row
jobsite_name = tk.StringVar()
combo_box = ttk.Combobox(frame1, font="none 12 bold", width=20, textvariable=jobsite_name, text="choose location")
combo_box.grid(row=0, column=1, sticky="wesn")
combo_box['values'] = [x for x in job_site]
# Left button side
ttk.Button(frame1, text='Run', command=start_analisys, ).grid(row=0, column=2, sticky='nsew', rowspan=3)
unified.mainloop()
Made three minor edits to your code: added a label to display the result, added a line to combo box setup, and changed the creation of the main window.
import tkinter as tk
from tkinter import ttk
def combo_box_updater():
total_location = ['linden', 'mineola', 'brooklyn']
return total_location
def start_analisys(event=None):
site = jobsite_name.get()
aLabel["text"] = site
print(site)
# this is part of a definition that automatically will update the names in later versions
job_site = combo_box_updater()
# basic gui setup
unified = tk.Tk()
unified.title('Unified 1 Week Timesheet')
unified.configure(background="#00012f")
unified.geometry("650x200")
unified.resizable(width=False, height=False)
entry_width = 30
# basic frame
frame1 = tk.Frame(unified)
frame1.grid(row=0, column=0, sticky='w')
# combo box in the fourth row
jobsite_name = tk.StringVar()
combo_box = ttk.Combobox(frame1, font="none 12 bold", width=20, textvariable=jobsite_name)
combo_box.grid(row=0, column=1, sticky="wesn")
combo_box['values'] = [x for x in job_site]
combo_box.current(0)
# Left button side
ttk.Button(frame1, text='Run', command=start_analisys, ).grid(row=0, column=2, sticky='nsew', rowspan=3)
# add a label
aLabel = ttk.Label(frame1, text='My Label')
# place the label
aLabel.grid(column=3, row=0)
unified.mainloop()
if __name__ == '__main__':
pass
When you add the values as an afterthought like that you need to add the corresponding commands as well. It's much better to add the values through the init method so the commands are automatically added:
jobsite_name = tk.StringVar(value="choose location")
combo_box = ttk.Combobox(frame1, textvariable=jobsite_name, values=job_site, font="none 12 bold", width=20)

Image not displaying in Tkinter Label widget

I'm trying to get an image to display in a Tkinter Label widget. This code works inside a class in PyCharm, but doesn't get past the 'tk.Label' line in the main app. I've consulted other answers here but haven't been able to figure out why the image isn't displaying in the main app.
logo_filepath = "/Users/xxx/MASTER/pymol/Master/cache/logos/tmpbhWv2Ts.gif"
self.img = tk.PhotoImage(file = logo_filepath)
self.logo = tk.Label(self, image=self.img)
self.logo.photo = self.img
self.logo.grid(row=0, column=3, rowspan=10, columnspan=4)
It's a very simple error. Just make sure that you aren't defining self.[Your Variable] outside of a class. Because self is only available in classes. Also, Here's my code:
import Tkinter as tk
root = tk.Tk()
logo_filepath = "Your File Path..."
img = tk.PhotoImage(file = logo_filepath)
logo = tk.Label(root, image=img)
logo.photo = img
logo.grid(row=0, column=3, rowspan=10, columnspan=4)
tk.mainloop()

Set Entry widget values dynamically in Tkinter

I have a window to browse a folder containing necessary files. I am using tkFileDialog for the same. I want to set the value of Entry widget equal to this selected folder. Initially when no folder is selected it will be null. As soon as I select the folder, the path of the selected folder should appear in the Entry widget. The user should be able to modify.Below mentioned is the code for the same.
from Tkinter import *
from tkFileDialog import *
class Checkit:
root = Tk()
#default string to be displayed in the entry of path
path_to_file = StringVar(root, value="abc")
def __init__(self):
self.inputDetail()
def inputDetail(self):
#copy the root window
master = self.root
#create frame for details in the root window
details_frame = Frame(master)
details_frame.grid(row=0, column=0)
#Create the Labels
papercode_label = Label(details_frame, text="Paper code:")
subject_label = Label(details_frame, text="Subject:")
chapter_label = Label(details_frame, text="Chapter:")
batch_label = Label(details_frame, text="Batch:")
ansFolder_label = Label(details_frame, text="Folder containing answer-keys:")
#create entry for the labels
papercode_entry = Entry(details_frame)
subject_entry = Entry(details_frame)
chapter_entry = Entry(details_frame)
batch_entry = Entry(details_frame)
ansFolder_entry = Entry(details_frame)
#create button to add path
path = Button(details_frame, text="Browse", command= lambda: self.addpath(details_frame))
#button to enter the next window
next = Button(details_frame, text="Next", command= lambda: self.checkOmr(details_frame, master))
#Use grid layout to place labels and entry
papercode_label.grid(row=0, sticky=W)
papercode_entry.grid(row=1, sticky=W)
subject_label.grid(row=2, sticky=W)
subject_entry.grid(row=3, column=0, sticky=W)
chapter_label.grid(row=4, sticky=W)
chapter_entry.grid(row=5, column=0, sticky=W)
batch_label.grid(row=6, sticky=W)
batch_entry.grid(row=7, column=0, sticky=W)
ansFolder_label.grid(row=8, sticky=W)
path.grid(row=9, sticky=W, columnspan=2)
next.grid(row=10, sticky=E, columnspan=2)
master.mainloop()
def checkOmr(self, old_frame, master):
#destoy the old frame
old_frame.destroy()
#create frame for details in the root window
inputPath_frame = Frame(master)
inputPath_frame.grid(row=0, column=0)
#create label to input folder containing
omrFolder_label = Label(inputPath_frame, text="Folder containing OMR sheet to be checked:")
#create button to add path
path = Button(inputPath_frame, text="Browse", command= lambda: self.addpath(inputPath_frame))
selected_path = Entry(inputPath_frame, textvariable=self.path_to_file)
#place the label and button on the grid
omrFolder_label.grid(row=0, sticky=W)
path.grid(row=1, column=0, sticky=W)
selected_path.grid(row=1, column=1, sticky=W)
#master.mainloop()
def addpath(self, details_frame):
self.path_to_file = askdirectory(parent=details_frame,initialdir="/",title='Please select a directory')
if __name__=='__main__':
handle = Checkit()
Here I am trying to change the modifying the self. path_to_file value on the click of the button. I tried to print the value of self.path_to_file value in addpath(). It gives correct result there but the value in the Entry selected_path in checkOMR() does not modify.
Can somebody suggest what changes should I make to make that thing possible.
Look at this line:
self.path_to_file = askdirectory(...)
Before this line of code runs, self.path_to_file is an instance of a StringVar. After this line of code has run, self.path_to_file is reset to be just a string.
Assuming you want self.path_to_file to remain an instance of StringVar, you need to change that line to this:
path = askdirectory(...)
self.path_to_file.set(path)

Categories