This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 5 years ago.
I want to display 2 different images when a button is pressed. I have two images, and corresponding 2 buttons. I'm using the panel's configure function to try to change the image but to no avail. How would I accomplish this? Thank you!
import Tkinter as tk
from PIL import ImageTk, Image
def next(panel):
path = "2.jpg"
img = ImageTk.PhotoImage(Image.open(path))
panel.configure(image=img)
panel.image = img # keep a reference!
def prev(panel):
path = "1.jpg"
img = ImageTk.PhotoImage(Image.open(path))
panel.configure(image=img)
panel.image = img # keep a reference!
#Create main window
window = tk.Tk()
#divide window into two sections. One for image. One for buttons
top = tk.Frame(window)
top.pack(side="top")
bottom = tk.Frame(window)
bottom.pack(side="bottom")
#place image
path = "1.jpg"
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(window, image = img)
panel.image = img # keep a reference!
panel.pack(side = "top", fill = "both", expand = "yes")
#place buttons
prev_button = tk.Button(window, text="Previous", width=10, height=2, command=prev(panel))
prev_button.pack(in_=bottom, side="left")
next_button = tk.Button(window, text="Next", width=10, height=2, command=next(panel))
next_button.pack(in_=bottom, side="right")
#Start the GUI
window.mainloop()
To pass arguments to a button callback command, you need the lambda keyword, else the functions will be called at the time of button creation.
#place buttons
prev_button = tk.Button(window, text="Previous", width=10, height=2, command=lambda: prev(panel))
prev_button.pack(in_=bottom, side="left")
next_button = tk.Button(window, text="Next", width=10, height=2, command=lambda: next(panel))
next_button.pack(in_=bottom, side="right")
Related
First: In code below i want to use instead of default rectangle button, images prepared by myslef.
This generates some problems (mayby with reference)? This button does not appear as image, also i am not able to use function (name: load_frame_insert()) after click.
Second: I wonder to have 2 bbtns:
Normal: assets/insert_data.png
OnClick: assets/insert_data2.png
Could you help me?
PS. Doesn't work after moving from up-down code to code with functions
import pyodbc
import pandas as pd
import os
import tkinter as tk
from PIL import ImageTk
# DB connector
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};'
'SERVER=onyx1905;'
'DATABASE=DW_15;'
'Trusted_Connection=yes')
# variables
name = os.getlogin()
cursor = conn.cursor()
running = True
bg_color_1 = "#205E61"
bg_button = "#1B4E51"
bg_button_ac = "#FFD966"
global img_button_1
def image_button_1(size):
img = tk.PhotoImage(file="assets/insert_data.png")
img = img.subsample(size, size)
return img
#button img: insert_data
#button img: insert_data_on_click
def clear_widgets(frame):
for widget in frame.winfo_children():
widget.destroy()
def load_main_frame():
clear_widgets(frame_insert)
frame_main.tkraise()
frame_main.pack_propagate(False)
# widget frame_main logo
logo_image = ImageTk.PhotoImage(file="assets/xrdl_logo.png")
logo_widget = tk.Label(frame_main, image=logo_image, bg=bg_color_1)
logo_widget.image = logo_image
logo_widget.pack()
# label on 1st frame
tk.Label(
frame_main,
text=(f" Hi {name}, please choose an action "),
bg=bg_button,
fg="white",
font=("TkMenuFont", 12)
).pack(pady=10)
# btn code on 1st frame
tk.Button(
frame_main,
image=image_button_1(1),
bd=0,
relief="groove",
compound=tk.CENTER,
bg=bg_color_1,
fg="yellow",
activeforeground="pink",
activebackground=bg_color_1,
font=("TkMenuFont", 12),
cursor="hand2",
text="",
command=lambda: load_frame_insert()
).pack(pady=5)
def load_frame_insert():
print("Hi XYZ")
# ini for app
main_app = tk.Tk()
main_app.title("SRD Loader")
main_app.eval("tk::PlaceWindow . center")
x = main_app.winfo_screenwidth() // 3
y = int(main_app.winfo_screenheight() * 0.1)
main_app.geometry('500x600+' + str(x) + '+' + str(y))
# frame look
frame_main = tk.Frame(main_app, width=500, height=600, bg=bg_color_1)
frame_insert = tk.Frame(main_app, width=500, height=600, bg=bg_color_1)
for frame in (frame_main, frame_insert):
frame.grid(row=0, column=0)
load_main_frame()
main_app.mainloop()
conn.close()
other related topics but doesnt work
youtube tutorials
For the statement command=image_button_1(1), the image returned by image_button_1(1) will be garbage collected because there is no variable referencing it. That is why you get a button without image.
You need to save the reference of the image, for example using an attribute of the button as below:
image = image_button_1(1)
btn = tk.Button(
frame_main,
image=image,
bd=0,
relief="groove",
compound=tk.CENTER,
bg=bg_color_1,
fg="yellow",
activeforeground="pink",
activebackground=bg_color_1,
font=("TkMenuFont", 12),
cursor="hand2",
text="",
command=lambda: load_frame_insert()
)
btn.pack(pady=5)
btn.image = image # save the reference of the image
I removed three libraries.
I removed image_button_1 function
Added image = tk.PhotoImage(file="p1.png")
Added variable for Button
Change 5 to 25 .pack(pady=25)
Removed lambda and brace bracket command=load_frame_insert
Snippet:
import os
import tkinter as tk
running = True
bg_color_1 = "#205E61"
bg_button = "#1B4E51"
bg_button_ac = "#FFD966"
def clear_widgets(frame):
for widget in frame.winfo_children():
widget.destroy()
def load_main_frame():
clear_widgets(frame_insert)
frame_main.tkraise()
frame_main.pack_propagate(False)
# widget frame_main logo
logo_image = tk.PhotoImage(file="p2.png")
logo_widget = tk.Label(frame_main, image=logo_image, bg=bg_color_1)
logo_widget.image = logo_image
logo_widget.pack()
# label on 1st frame
tk.Label(
frame_main,
text=(f"Hi please choose an action"),
bg=bg_button,
fg="white",
font=("TkMenuFont", 12)
).pack(pady=10)
image = tk.PhotoImage(file="p1.png")
# btn code on 1st frame
btn= tk.Button(
frame_main,
image=image,
bd=0,
relief="groove",
compound=tk.CENTER,
bg=bg_color_1,
fg="yellow",
activeforeground="pink",
activebackground=bg_color_1,
font=("TkMenuFont", 12),
cursor="hand2",
text="",
command=load_frame_insert
)
btn.pack(pady=25)
btn.image = image
def load_frame_insert():
print("Hi XYZ")
# ini for app
main_app = tk.Tk()
main_app.title("SRD Loader")
main_app.eval("tk::PlaceWindow . center")
x = main_app.winfo_screenwidth() // 3
y = int(main_app.winfo_screenheight() * 0.1)
main_app.geometry('500x600+' + str(x) + '+' + str(y))
# frame look
frame_main = tk.Frame(main_app, width=500, height=600, bg=bg_color_1)
frame_insert = tk.Frame(main_app, width=500, height=600, bg=bg_color_1)
for frame in (frame_main, frame_insert):
frame.grid(row=0, column=0)
load_main_frame()
main_app.mainloop()
Screenshot:
This question already has answers here:
Tkinter vanishing PhotoImage issue [duplicate]
(1 answer)
Why does Tkinter image not show up if created in a function?
(5 answers)
Closed 29 days ago.
hello i try to build a simpel watermark app
i user custom tkinter for user interface ( its same to tkinter )
when i upload a picture with button my function everything work expact picture in canvas i see the canvas but i dont see a picture i test the code with a text on canvas and its show when i add a label with same photo ( i comment that line in this cod) even i dont grid it on window my picture show in canvas this is my cod :
import customtkinter
from PIL import Image, ImageTk
my_font1 = ('times', 18, 'bold')
customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("dark-blue")
window = customtkinter.CTk()
window.title("Water mark Photo")
window.config(padx=50, pady=50)
window.geometry("600x600")
input_pic_label = customtkinter.CTkLabel(master=window,
text="Choose Your Photo",
font=my_font1)
input_pic_label.grid(row=0, column=0, padx=(180, 0), pady=(200, 0))
choose_pic_button = customtkinter.CTkButton(master=window,
text="Upload Photo",
command=lambda: upload_file())
choose_pic_button.grid(row=1, column=0, padx=(180, 0))
def upload_file():
choose_pic_button.destroy()
input_pic_label.destroy()
f_types = [('Jpg Files', '*.jpg'), ('Png Files', '*.png')]
filename = customtkinter.filedialog.askopenfilename(filetypes=f_types)
image = Image.open(filename)
original_image_size = image.size
print(original_image_size)
resized_image = image.resize((500, 500))
resized_image.save("temp.jpg")
new_image = ImageTk.PhotoImage(resized_image)
canvas = customtkinter.CTkCanvas(master=window, width=500, height=500, highlightthickness=0, bg="black")
canvas.grid(row=2, column=1, columnspan=2)
canvas.create_image(250, 250, image=new_image)
window.update()
# label = customtkinter.CTkLabel(master=window, text="", image=new_image)
window.mainloop()
i expect to see a picture but its show nothing i also try to di it in tkinter with the blow cod but output its same expect i get nothing as outpout here without any error:
import tkinter
from PIL import Image, ImageTk
from tkinter import filedialog
my_font1 = ('times', 18, 'bold')
window = tkinter.Tk()
window.title("Water mark Photo")
window.config(padx=50, pady=50)
input_pic_label = tkinter.Label(window,
text="Choose Your Photo",
font=my_font1)
input_pic_label.grid(row=0, column=0, padx=(180, 0))
choose_pic_button = tkinter.Button(window,
text="Upload Photo",
command=lambda: upload_file())
choose_pic_button.grid(row=1, column=0, padx=(180, 0))
canvas = tkinter.Canvas(window, width=500, height=500, highlightthickness=0)
text = canvas.create_text(250, 250, text="Your image")
canvas.grid(row=2, column=1, columnspan=2)
def upload_file():
#choose_pic_button.destroy()
#input_pic_label.destroy()
#canvas.itemconfig(text, text="")
f_types = [('Jpg Files', '*.jpg'), ('Png Files', '*.png')]
filename = tkinter.filedialog.askopenfilename(filetypes=f_types)
image = Image.open(filename)
img = ImageTk.PhotoImage(Image.open(filename))
original_image_size = image.size
print(original_image_size)
resized_image = image.resize((500, 500))
resized_image.save("temp.jpg")
resized_image = ImageTk.PhotoImage(resized_image)
canvas.create_image(250, 250, image=resized_image)
label = tkinter.Label(window, text="helloooooo", image=resized_image)
label.grid(row=2, column=4)
window.mainloop()
I am attempting to create a simple photo editing application that allows a user to paste a logo onto a selected image.
However, when I try to use the .paste function to paste the logo onto the current image I get the error "ValueError: cannot determine region size; use 4-item box".
Help would be greatly appreciated. Thank you fellow coders.
# PHOTO EDITING SCREEN
def edit_screen():
# REFERENCE GLOBAL WINDOW
global home_window, current_image, image_counter, all_files, image_container, canvas, add_images_button_count, \
max_image
# CLEAR PREVIOUS WINDOW CANVAS
clear_screen()
# SPECIFY WINDOW SIZE
home_window.geometry("600x450")
# CREATES TOP FRAME AND DOESN'T ALLOW WINDOW SHRINKAGE
header_frame = Frame(home_window, width=600, height=50, bd=5, bg="grey")
header_frame.grid(row=0)
# BUTTONS
close = Button(header_frame, text="Close App", bg="white", fg="blue", command=close_app)
close.place(relx=0.015, rely=0.2, anchor="nw")
back = Button(header_frame, text="Back", bg="white", fg="blue", command=back_button)
back.place(relx=0.13, rely=0.2, anchor="nw")
add_text = Button(header_frame, text="Add Text", bg="white", fg="blue", command=add_text_button)
add_text.place(relx=0.38, rely=0.2, anchor="nw")
add_logo = Button(header_frame, text="Add Logo", bg="white", fg="blue", command=add_logo_button)
add_logo.place(relx=0.485, rely=0.2, anchor="nw")
clear = Button(header_frame, text="Clear", bg="white", fg="blue", command=clear_edits)
clear.place(relx=0.63, rely=0.2, anchor="n")
save = Button(header_frame, text="Save", bg="blue", fg="white", command=save_button)
save.place(relx=0.985, rely=0.2, anchor="ne")
# MULTIPLE IMAGE ERROR HANDLING
try:
# LOGIC TO DISPLAY EACH PICTURE
# ACCESS CURRENT IMAGE
f = all_files[image_counter]
# OPEN AS IMAGE
current_image = Image.open(f)
# TK PHOTO
resized_img = ImageTk.PhotoImage(current_image.resize((500, 400)))
# PLACE IMAGE ON CANVAS
image_container = canvas.create_image(300, 210, image=resized_img)
except IndexError:
# RESET IMAGE BUTTON COUNT VARIABLE
add_images_button_count = 0
# RESET MAX IMAGE COUNT VARIABLE
max_image = []
# RESET IMAGE COUNTER
image_counter = 0
# REDIRECT TO HOME SCREEN SINCE NO MORE PHOTOS EXIST
home_screen()
# RUN A NON RESIZEABLE TKINTER WINDOW
home_window.resizable(False, False)
# CLOSING WINDOW PROTOCOL
home_window.protocol("WM_DELETE_WINDOW", close_app)
# RUN WINDOW
home_window.mainloop()
# UPLOAD LOGO
def add_logo_function(x_logo_position, y_logo_position):
# REFERENCE GLOBAL VARIABLES
global canvas, current_image, image_container
# SPECIFY FILE TYPES
filetypes = [('JPG Files', '*.jpg'), ('PNG Files', '*.png')]
# OPEN FILE EXPLORER AND ALLOW USER TO SELECT LOGO
filename = askopenfilename(filetypes=filetypes)
# OPEN AS IMAGE
img = Image.open(filename)
# RESIZE IMAGE
img_resized = img.resize((100, 100))
# TK PHOTO IMAGE
img = ImageTk.PhotoImage(img_resized)
# PASTE LOGO ONTO CURRENT IMAGE
current_image.paste(img, (x_logo_position.get(), y_logo_position.get()))
I'm building an app that's supposed to display various images from a local folder depending on which button is clicked in the app.
So far, I have started out with an example I've found and try to modify it, but I can't figure out how to summon a .jpg or .png via a button click in the first place. Here's my very basic code so far:
import tkinter as tk
def write_slogan():
print("Tkinter is easy to use!")
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
button = tk.Button(frame,
text="QUIT",
fg="red",
command=quit)
button.pack(side=tk.LEFT)
slogan = tk.Button(frame,
text="Hello",
command=write_slogan)
slogan.pack(side=tk.LEFT)
root.mainloop()
Essentially, instead of writing the slogan in the console, I would like the button click to trigger an image being displayed. How would I go about achieving that?
I have amended your code so when you click your button the image "test.png" will display on a label.
Here is the code for testing, in my case "test.png" was in the same directory as my Python script.
import tkinter as tk
render = None
def write_slogan():
# get image and display
image = tk.PhotoImage(file = "test.png")
imageLabel.configure(image = image)
imageLabel.image = image
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
button = tk.Button(frame,
text="QUIT",
fg="red",
command=quit)
button.pack(side=tk.LEFT)
slogan = tk.Button(frame,
text="Hello",
command=write_slogan)
slogan.pack(side=tk.LEFT)
imageLabel = tk.Label(frame)
imageLabel.pack(side=tk.LEFT)
root.mainloop()
Also, this thread was helpful.
You can pass the image filename to the function, so that different buttons show different images:
import tkinter as tk
from PIL import ImageTk
def show_image(imagefile):
image = ImageTk.PhotoImage(file=imagefile)
imagebox.config(image=image)
imagebox.image = image # save a reference of the image to avoid garbage collection
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
button = tk.Button(frame, text="QUIT", fg="red", command=quit)
button.pack(side=tk.LEFT)
slogan = tk.Button(frame, text="Hello", command=lambda: show_image("slogan.png"))
slogan.pack(side=tk.LEFT)
other = tk.Button(frame, text="World", command=lambda: show_image("other.jpg"))
other.pack(side=tk.LEFT)
# label to show the image
imagebox = tk.Label(root)
imagebox.pack()
root.mainloop()
Since tk.PhotoImage() does not support JPG image, external Pillow module is used instead.
How do I create an image in button. Instead of having text saying "Draw" I want it to be a picture of a brush.
Code:
self.draw_button = Button(self.root, text='Draw', command=self.use_draw)
self.draw_button.grid(row=0, column=2)
Create an image with tkinter's PhotoImage then set it inside Button.
from tkinter import *
root = Tk()
img = PhotoImage(file='paint_brush.png')
draw_button = Button(root, image=img)
draw_button.grid(row=0, column=0)
root.mainloop()