TKinter background resizer + buttons/labels - python

I'm trying to setup tkinter gui screen with wallpaper on the background when the bg image fit the resize of the screen, i have took code from here..but the problem is when i'm trying to put buttons on it or another labels, the wallpaper still stay on the top and i can't see them.
Here the code:
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
root.title("Title")
root.geometry("800x600")
class Example(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.configure(background="black")
self.grid(sticky=N+S+E+W)
self.image = Image.open("bg.jpg")
self.img_copy= self.image.copy()
self.background_image = ImageTk.PhotoImage(self.image)
self.background = Label(self, image=self.background_image)
self.background.grid(row =0, column =0,sticky="nsew")
self.background.grid_rowconfigure(0, weight=1)
self.background.grid_columnconfigure(0, weight=1)
self.master = master
self.master.bind('<Configure>', self._resize_image)
# create a button
self.button= Button(root, text="EXIT", width=4).grid(row=3, column=1, sticky=N+S+E+W)
def _resize_image(self,event):
new_width = self.master.winfo_width()
new_height = self.master.winfo_height()
self.image = self.img_copy.resize((new_width, new_height))
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image = self.background_image)
e = Example(root)
e.grid(row =0, column =0,sticky="nsew")
e.grid_rowconfigure(0, weight=1)
e.grid_columnconfigure(0, weight=1)
root.mainloop()

You need to use place() to put the background image so that it does not interfere other widgets in the same parent.
Below is a simplified example based on your code:
from tkinter import *
from PIL import Image, ImageTk
class Example(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.configure(background="black")
self.image = Image.open("bg.jpg")
# label for the background image
self.background = Label(self)
self.background.place(x=0, y=0)
self.bind('<Configure>', self._resize_image)
# create a button
self.button = Button(self, text="EXIT", width=4)
self.button.grid(row=3, column=1, sticky=N+S+E+W, padx=50, pady=50)
def _resize_image(self,event):
if event.widget is self:
# resize background image to fit the frame size
image = self.image.resize((event.width, event.height))
self.background_image = ImageTk.PhotoImage(image)
self.background.configure(image=self.background_image)
root = Tk()
root.title("Title")
root.geometry("800x600")
e = Example(root)
e.pack(fill=BOTH, expand=1)
root.mainloop()

Related

python tkinter resize background image according to window size

The background image is not adjusting automatically to the window size in python using tkinter
Following is the code snippet
self.background_image = tk.PhotoImage(file="background.png")
self.background_label = tk.Label(self.master, image=self.background_image)
self.background_label.pack(fill='both', expand=True)
The image should be in background of the behind all the GUI components.
The code is actually a part of a python GUI but the image is not resizing automatically according to the window size previously i tried this but it was to add a static image but in need the image to fit automatically to the window size
This is the kinda the complete code
import tkinter as tk
from tkinter import ttk
class MongoDBGUI:
def __init__(self, master):
self.master = master
self.master.title("MongoDB Cloud Search and Display")
self.master.geometry("1000x400")
self.background_image = tk.PhotoImage(file="background.png")
self.background_label = tk.Label(self.master, image=self.background_image)
self.background_label.place(relwidth=1, relheight=1)
self.label = tk.Label(self.master, text="Enter search criteria:")
self.label.pack()
self.entry = tk.Entry(self.master)
self.entry.pack()
self.search_button = tk.Button(self.master, text="Search", command=self.search)
self.search_button.pack()
self.tree = ttk.Treeview(self.master)
self.tree.pack()
self.tree["columns"] = ("transcript", "audio_file", "audio")
self.tree.column("transcript", width=400, anchor="center")
self.tree.column("audio_file", width=150, anchor="center")
self.tree.column("audio", width=50, anchor="center")
self.tree.heading("transcript", text="Transcript")
self.tree.heading("audio_file", text="Audio File Number")
self.tree.heading("audio", text="Audio")
This is an not so easy task. If you want to have a resizable image then you need to use the PIL package. Additionally a further method is needed to rezise the image dynamically. Ofcourse if the window size always stays the same the solution could be implemented like :
self.image = self.img_copy.resize((new_width, new_height))
#resize is included in the PIL.Image module
To dynamically resize the background Picture the code could look like this:
import tkinter as tk
from tkinter import ttk
from scipy import misc,datasets
from PIL import Image, ImageTk
class MongoDBGUI:
def __init__(self, master):
self.master = master
self.master.title("MongoDB Cloud Search and Display")
self.master.geometry("1000x400")
self.image = Image.open("background.png")
self.background_image = ImageTk.PhotoImage(self.image)
self.img_copy = self.image.copy()
self.background_label = tk.Label(self.master, image=self.background_image)
self.background_label.place(relwidth=1, relheight=1)
self.label = tk.Label(self.master, text="Enter search criteria:")
self.label.pack()
self.entry = tk.Entry(self.master)
self.entry.pack()
self.search_button = tk.Button(self.master, text="Search", command=self.search)
self.search_button.pack()
self.tree = ttk.Treeview(self.master)
self.tree.pack()
self.tree["columns"] = ("transcript", "audio_file", "audio")
self.tree.column("transcript", width=400, anchor="center")
self.tree.column("audio_file", width=150, anchor="center")
self.tree.column("audio", width=50, anchor="center")
self.tree.heading("transcript", text="Transcript")
self.tree.heading("audio_file", text="Audio File Number")
self.tree.heading("audio", text="Audio")
self.background_label.bind('<Configure>', self._resize_image)
def _resize_image(self,event):
new_width = event.width
new_height = event.height
self.image = self.img_copy.resize((new_width, new_height))
self.background_image = ImageTk.PhotoImage(self.image)
self.background_label.configure(image = self.background_image)
master=tk.Tk()
test=MongoDBGUI(master)
master.mainloop()

How to add buttons and labels on frame if its resizable

i have a code:
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
root.geometry("900x580")
class Example(Frame):
def __init__(self, master, *pargs):
Frame.__init__(self, master, *pargs)
self.image = Image.open("eth_background.png")
self.img_copy= self.image.copy()
self.background_image = ImageTk.PhotoImage(self.image)
self.background = Label(self, image=self.background_image)
self.background.pack(fill=BOTH, expand=YES)
self.background.bind('<Configure>', self._resize_image)
self.widget = Button(self, text='Hello world', command=self.quit)
self.widget.pack(side=LEFT)
def _resize_image(self,event):
new_width = event.width
new_height = event.height
self.image = self.img_copy.resize((new_width, new_height))
self.background_image = ImageTk.PhotoImage(self.image)
self.background.configure(image = self.background_image)
e = Example(root)
e.pack(fill=BOTH, expand=YES)
root.mainloop()
I did that bacground is automaticly resize, but now i cant add buttons or lables on a frame. I found it:
from Tkinter import *
class Hello(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.pack()
self.make_widgets()
def make_widgets(self):
widget = Button(self, text='Hello world', command=self.quit)
widget.pack(side=LEFT)
if __name__ == '__main__': Hello().mainloop()
but it obviously doesnt work, how i can do that frame, resizable bacground, and buttons on it?

How to use 2nd Tkinter window to change image in 1st?

Quick summary: The green button is supposed to change when an image is selected, but it doesn't:
I have a Tkinter window-A with a button that when pressed will use a separate Python file to create a new window-B. Window-B has two buttons: new screen-snip or select image from folder. The method used for this is supposed to then change self.image_selected so that it can be used to update the button in window-A to have this new image.
I've tried both lines of code below, and neither are working. I'm not getting any errors either:
self.button.configure(image = img.image_selected) # first try
self.button['image'] = img.image_selected # second try
Here is my code (simplified for clarity):
import tkinter as tk
import get_image_or_snip
class ButtonImg:
def __init__(self, master):
self.newWindow = None
self.master = master
self.title = "My Minimum Reproducible Example"
self.fontA = ("arial", 20, "bold")
self.canvas = tk.Canvas(height = 5)
self.canvas.pack()
self.button = tk.Button(bg="#93d9cc", height = 5, text = "Select Image",
font = self.fontA, command = self.changeImage)
self.button.pack(fill="both")
def changeImage(self):
self.newWindow = tk.Toplevel(self.master)
img = get_image_or_snip.AcquireImage(self.newWindow)
self.button.configure(image = img.image_selected)
#self.button['image'] = img.image_selected
root = tk.Tk()
app = ButtonImg(root)
root.mainloop()
Here is the aforementioned get_image_or_snip.py code:
import tkinter as tk
from tkinter import filedialog
from PIL import ImageTk, Image
import snipping_tool
class AcquireImage:
def __init__(self, master):
self.master = master
self.fontA = ("arial", 20, "bold")
self.frame = tk.Frame(master, bg="#1B2631")
self.frame.pack(fill="both", expand=True)
self.button1 = tk.Button(self.frame, text="Select Image File", padx=10, pady=10, bg="#d9a193",
font = self.fontA, command =lambda: self.show_dialogs(1))
self.button1.grid(row=0, column=0, sticky="nsew")
self.button2 = tk.Button(self.frame, text="Get Screen Snip", padx=10, pady=10, bg="#d9a193",
font = self.fontA, command=lambda: self.show_dialogs(2))
self.button2.grid(row=0, column=1, sticky="nsew")
self.image_selected = None
self.master.mainloop()
def show_dialogs(self, method):
if method == 1:
ret = filedialog.askopenfilename()
load_img = Image.open(ret)
self.image_selected = ImageTk.PhotoImage(load_img)
if method == 2:
ret = snipping_tool.get_snip()
self.image_selected = ret
def main():
root = tk.Tk()
AcquireImage(root)
root.mainloop()
if __name__ == '__main__':
main()
If you add print() before and after get_image_or_snip.AcquireImage(self.newWindow) in changeImage() then you should see only first text because you run second mainloop() and it never ends this loop and never go back to changeImage() and never runs self.button.configure(image=img.image_selected)
You should use only one mainloop() and eventually use
root.wait_window(self.newWindow)
to wait until you close second window and then it will run self.button.configure(image=img.image_selected)
But there are other problems.
It removes image from memory memory when second windows is destroyed so you have to assign it to variable in first window.
Button use height in chars when you sent text but when you assign image then it use height in pixels and you have to change it from 5 to image.height()`
All code in one file
import tkinter as tk
from tkinter import filedialog
from PIL import ImageTk
class AcquireImage:
def __init__(self, master):
self.master = master
self.fontA = ("arial", 20, "bold")
self.frame = tk.Frame(master, bg="#1B2631")
self.frame.pack(fill="both", expand=True)
self.button1 = tk.Button(self.frame, text="Select Image File", padx=10, pady=10, bg="#d9a193",
font=self.fontA, command=lambda:self.show_dialogs(1))
self.button1.grid(row=0, column=0, sticky="nsew")
self.button2 = tk.Button(self.frame, text="Get Screen Snip", padx=10, pady=10, bg="#d9a193",
font=self.fontA, command=lambda:self.show_dialogs(2))
self.button2.grid(row=0, column=1, sticky="nsew")
self.image_selected = None
def show_dialogs(self, method):
if method == 1:
ret = filedialog.askopenfilename(initialdir='/home/user/images/')
if ret:
self.image_selected = ImageTk.PhotoImage(file=ret)
self.master.destroy()
elif method == 2:
self.image_selected = snipping_tool.get_snip()
class ButtonImg:
def __init__(self, master):
self.newWindow = None
self.master = master
self.title = "My Minimum Reproducible Example"
self.fontA = ("arial", 20, "bold")
self.canvas = tk.Canvas(height=5)
self.canvas.pack()
self.button = tk.Button(bg="#93d9cc", height=5, text="Select Image",
font=self.fontA, command=self.changeImage)
self.button.pack(fill="both")
def changeImage(self):
print('open second window')
self.newWindow = tk.Toplevel(self.master)
img = AcquireImage(self.newWindow)
self.master.wait_window(self.newWindow)
print('close second window')
if img.image_selected: # check if image was selected
self.image = img.image_selected
self.button.configure(image=self.image, height=self.image.height())
root = tk.Tk()
app = ButtonImg(root)
root.mainloop()
BTW: If you want to change image without closing second window then you should send first window (or button from first window) as argument to second window and change image in show_dialogs()
import tkinter as tk
from tkinter import filedialog
from PIL import ImageTk
class AcquireImage:
def __init__(self, master, first_window):
self.master = master
self.first_window = first_window
self.fontA = ("arial", 20, "bold")
self.frame = tk.Frame(master, bg="#1B2631")
self.frame.pack(fill="both", expand=True)
self.button1 = tk.Button(self.frame, text="Select Image File", padx=10, pady=10, bg="#d9a193",
font=self.fontA, command=lambda:self.show_dialogs(1))
self.button1.grid(row=0, column=0, sticky="nsew")
self.button2 = tk.Button(self.frame, text="Get Screen Snip", padx=10, pady=10, bg="#d9a193",
font=self.fontA, command=lambda:self.show_dialogs(2))
self.button2.grid(row=0, column=1, sticky="nsew")
self.image_selected = None
def show_dialogs(self, method):
if method == 1:
ret = filedialog.askopenfilename(initialdir='/home/user/images/')
if ret:
self.image_selected = ImageTk.PhotoImage(file=ret)
self.first_window.image = self.image_selected
self.first_window.button.configure(image=self.first_window.image, height=self.first_window.image.height())
elif method == 2:
self.image_selected = snipping_tool.get_snip()
class ButtonImg:
def __init__(self, master):
self.newWindow = None
self.master = master
self.title = "My Minimum Reproducible Example"
self.fontA = ("arial", 20, "bold")
self.canvas = tk.Canvas(height=5)
self.canvas.pack()
self.button = tk.Button(bg="#93d9cc", height=5, text="Select Image",
font=self.fontA, command=self.changeImage)
self.button.pack(fill="both")
def changeImage(self):
self.newWindow = tk.Toplevel(self.master)
img = AcquireImage(self.newWindow, self) # first window as `self` but you can send `self.button`
root = tk.Tk()
app = ButtonImg(root)
root.mainloop()
EDIT: Doc about creating Dialog Windows

How do I make the background in a tkinter window transparent?

How do I make this so the window background is transparent, but the image remains visible?
Here is my code;
from tkinter import Tk, Label, Button, Canvas
from PIL import ImageTk, Image
class MyFirstGUI:
def __init__(self, master):
self.canvas = Canvas(master, width = 300, height = 300)
self.canvas.pack()
self.image = ImageTk.PhotoImage(Image.open("Sprites/ph1.png"))
self.canvas.create_image(150, 150, image=self.image)
self.master = master
master.title("A simple GUI")
self.close_button = Button(master, text="Close", command=master.quit)
self.close_button.pack()
def greet(self):
print("Greetings!")
root = Tk()
root.geometry("+1630+775")
root.overrideredirect(1)
my_gui = MyFirstGUI(root)
root.mainloop()

Can't seem to change the window background colour in tkinter

Here is my code so far for a GUI I am making in tkinter, I have attempted to change the background colour of the window but it doesn't seem to work.
from tkinter import *
from tkinter.font import Font
class Window(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("Main Menu")
self.pack(fill=BOTH, expand=1)
videoButton = Button(self, text="Video Mode", font=helv18, bg="white", height=1, width=18)
videoButton.place(relx=0.5, rely=0.35, anchor=CENTER)
timelapseButton = Button(self, text="Time-lapse Mode", font=helv18, bg="white", height=1, width=18)
timelapseButton.place(relx=0.5, rely=0.6, anchor=CENTER)
root = Tk()
helv18 = Font(family='Helvetica', size=18, weight='bold')
root.config(bg='black')
root.geometry("480x320")
root.resizable(0, 0)
app = Window(root)
root.mainloop()

Categories