How to show images from path in new window in python tk - python-3.x

After browsing path of image i wanna show image on next window in python using Tk library but image is not showing in next window. please take a look on my code below and give answer Thanks.
import tkinter as tk
from tkinter import filedialog as fd
a=""
str1 = "e"
class Browse(tk.Frame):
""" Creates a frame that contains a button when clicked lets the user to select
a file and put its filepath into an entry.
"""
def __init__(self, master, initialdir='', filetypes=()):
super().__init__(master)
self.filepath = tk.StringVar()
self._initaldir = initialdir
self._filetypes = filetypes
self._create_widgets()
self._display_widgets()
def _create_widgets(self):
self._entry = tk.Entry(self, textvariable=self.filepath, font=("bold", 10))
a=self._entry
self._button = tk.Button(self, text="Browse...",bg="red",fg="white", command=self.browse)
self._classify=tk.Button(self,text="Classify",bg="red",fg="white", command=self.classify)
self._label=tk.Label(self, text="IMAGE CLASSIFICATION USING DEEP LERAINING.", bg="blue", fg="white",height=3, font=("bold", 14))
def _display_widgets(self):
self._label.pack(fill='y')
self._entry.pack(fill='x', expand=True)
self._button.pack(fill='y')
self._classify.pack(fill='y')
def retrieve_input(self):
#str1 = self._entry.get()
#a=a.replace('/','//')
print (str1)
def classify(self):
newwin = tk.Toplevel(root)
newwin.geometry("500x500")
label = tk.Label(newwin, text="Classification", bg="blue", fg="white",height=3, font=("bold", 14))
label.pack()
canvas = tk.Canvas(newwin, height=300, width=300)
canvas.pack()
my_image = tk.PhotoImage(file=a, master=root)
canvas.create_image(150, 150, image=my_image)
newwin.mainloop()
def browse(self):
""" Browses a .png file or all files and then puts it on the entry.
"""
self.filepath.set(fd.askopenfilename(initialdir=self._initaldir,
filetypes=self._filetypes))
if __name__ == '__main__':
root = tk.Tk()
labelfont = ('times', 10, 'bold')
root.geometry("500x500")
filetypes = (
('Portable Network Graphics', '*.png'),
("All files", "*.*")
)
file_browser = Browse(root, initialdir=r"C:\Users",
filetypes=filetypes)
file_browser.pack(fill='y')
root.mainloop()

Your global variable a which stores the path of the image is not getting updated. You need to explicitly do it. Below is the code that works. Have a look at the browse() function.
import tkinter as tk
from tkinter import filedialog as fd
a=""
str1 = "e"
class Browse(tk.Frame):
""" Creates a frame that contains a button when clicked lets the user to select
a file and put its filepath into an entry.
"""
def __init__(self, master, initialdir='', filetypes=()):
super().__init__(master)
self.filepath = tk.StringVar()
self._initaldir = initialdir
self._filetypes = filetypes
self._create_widgets()
self._display_widgets()
def _create_widgets(self):
self._entry = tk.Entry(self, textvariable=self.filepath, font=("bold", 10))
a = self._entry
self._button = tk.Button(self, text="Browse...",bg="red",fg="white", command=self.browse)
self._classify=tk.Button(self,text="Classify",bg="red",fg="white", command=self.classify)
self._label=tk.Label(self, text="IMAGE CLASSIFICATION USING DEEP LERAINING.", bg="blue", fg="white",height=3, font=("bold", 14))
def _display_widgets(self):
self._label.pack(fill='y')
self._entry.pack(fill='x', expand=True)
self._button.pack(fill='y')
self._classify.pack(fill='y')
def retrieve_input(self):
#str1 = self._entry.get()
#a=a.replace('/','//')
print (str1)
def classify(self):
global a
newwin = tk.Toplevel(root)
newwin.geometry("500x500")
label = tk.Label(newwin, text="Classification", bg="blue", fg="white",height=3, font=("bold", 14))
label.pack()
canvas = tk.Canvas(newwin, height=300, width=300)
canvas.pack()
my_image = tk.PhotoImage(file=a, master=root)
canvas.create_image(150, 150, image=my_image)
newwin.mainloop()
def browse(self):
""" Browses a .png file or all files and then puts it on the entry.
"""
global a
a = fd.askopenfilename(initialdir=self._initaldir, filetypes=self._filetypes)
self.filepath.set(a)
if __name__ == '__main__':
root = tk.Tk()
labelfont = ('times', 10, 'bold')
root.geometry("500x500")
filetypes = (
('Portable Network Graphics', '*.png'),
("All files", "*.*")
)
file_browser = Browse(root, initialdir=r"~/Desktop", filetypes=filetypes)
file_browser.pack(fill='y')
root.mainloop()
P.S. Do change your initialdir. I changed it as I am not on Windows.

Related

Tkinter - label doesn't update

This morning I started to work on a little app so I can understand better TkInter.
I didn't get too far because I can't make the label to update after I press a button.
It seems like after I create an instance of the Label object I can't work on it anymore because of the mainloop() I guess? I tried to use .update() and other ways to make this work but I can't figure it out. If I add () to file_explorer method, the label updates but I can't open the file explorer anymore and it also starts the file explorer without pressing the button so it's pointless. Found something here on StackOverflow but still nothing.
from tkinter import *
from tkinter import filedialog as fd
import os
# Main_window
App = Tk()
App.geometry("300x300")
App.resizable(0, 0)
filename = "empty"
class Btn:
def __init__(self, master, pos_x, pos_y, label):
frame = Frame(master)
frame.pack()
self.Button = Button(master, text=label, command=self.file_explorer)
self.Button.place(x=pos_x, y=pos_y)
def file_explorer(self):
global filename
filename = fd.askopenfilename(filetypes=(('text files', '*.txt'), ('All files', '*.*')))
filename = os.path.basename(filename)
class FileLabel:
def __init__(self, master, pos_x, pos_y):
global filename
frame = Frame(master)
frame.pack()
self.label1 = Label(master, text=filename)
self.label1.place(x=pos_x, y=pos_y)
e = Btn(App, 10, 10, "Browse file")
f = FileLabel(App, 90, 12)
App.mainloop()
Updating filename will not update the label automatically. However, you can use StringVar instead of normal string and textvariable option of Label to achieve the goal:
...
filename = StringVar(value="empty")
class Btn:
def __init__(self, master, pos_x, pos_y, label):
frame = Frame(master)
frame.pack()
self.Button = Button(master, text=label, command=self.file_explorer)
self.Button.place(x=pos_x, y=pos_y)
def file_explorer(self):
fname = fd.askopenfilename(filetypes=(('text files', '*.txt'), ('All files', '*.*')))
# update filename
filename.set(os.path.basename(fname))
class FileLabel:
def __init__(self, master, pos_x, pos_y):
frame = Frame(master)
frame.pack()
self.label1 = Label(master, textvariable=filename) # used textvariable instead
self.label1.place(x=pos_x, y=pos_y)
...

I need help making a tkinter program that variably opens a picture

I'm trying to make a program that has a button that will open a picture if a variable is in a certain state, and change how the button looks (or maybe show a different picture) if it's not. I have been trying to work through the bugs I've been getting.
This is honestly intermediary code so I can understand how to make what I'm actually trying to do, make a network-enabled GUI for some physical buttons.
I've tried passing blueButton in as a variable, but that didn't work.
import tkinter as tk
weather = "sunny"
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.create_widgets()
def create_widgets(self):
self.blueButton = tk.Button(self, fg = "blue")
self.blueButton["text"] = "I'm Blue"
self.blueButton["command"] = self.change
self.blueButton.pack(anchor="nw")
self.quit = tk.Button(self, text = "QUIT", fg = "red",
command = self.master.destroy)
self.quit.pack(side="bottom")
self.pack(fill = "both", expand = 1)
def change(self):
global weather
if weather == "sunny":
w = tk.Canvas(root, width=400, height=750)
img = tk.PhotoImage(file = "haunter.gif")
w.create_image((200, 200), image = img)
w.pack()
else:
self.blueButton["bitmap"] = "error"
root = tk.Tk()
root.geometry("400x300")
app = Application(master = root)
app.mainloop()
The canvas gets made, but the picture doesn't show up, the "quit" button just moves.
I've also gotten the error "name blueButton is not defined".
You could keep the image as an attribute of your App, put it on a canvas, then show or hide the canvas depending on the weather.
import random
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.create_widgets()
def create_widgets(self):
self.blueButton = tk.Button(self, fg = "blue")
self.blueButton["text"] = "I'm Blue"
self.blueButton["command"] = self.change
self.blueButton.pack()
self.quit = tk.Button(self, text = "QUIT", fg = "red",
command = self.master.destroy)
self.quit.pack()
self.pack(fill = "both", expand = 1)
self.canvas = tk.Canvas(root, width=400, height=750)
# self.sunny_img = tk.PhotoImage(file="haunter.gif")
self.sunny_img = tk.PhotoImage(file="rapporteur.gif")
self.canvas.create_image((200, 200), image=self.sunny_img)
def change(self):
weather = ['sunny', 'rainy']
current_weather = random.choice(weather)
if current_weather == 'sunny':
self.canvas.pack()
self.blueButton["bitmap"] = ''
else:
self.canvas.pack_forget()
self.blueButton["bitmap"] = "error"
root = tk.Tk()
root.geometry("400x300")
app = Application(master = root)
app.mainloop()

Python tkinter disable "submit" button until all fields are populated

I am still relatively new at Python, but I am making a GUI app that has 2 entry fields and two filedialog buttons for the user to select the file to import and the directory to save the output of the program. I am trying to do some validation on the entry fields to make sure that the user cannot click on the submit button until the entry fields are filled in and they have selected a file to import and a directory to save the output.
I got some of the way, but I'm stuck and I'm afraid I don't know enough about classes and methods to determine why I cannot change the status of my submit_button.config?
I have read various examples of how to do validation to entry fields including using validatecommand and building a validate method within my class. I abandoned that because I could not figure out how to validate multiple fields within the submit_button command.
Here is my code as it sits right now. I am struggling with the validate method within the Application class.
import pandas as pd
import numpy as np
from tkinter import *
from tkinter import ttk
from tkinter import filedialog as fd
from tkinter import messagebox
import os
class FileLogic:
def __init__(self, path, save_location, request_id, exeuction_id):
self.path = path
self.save_location = save_location
self.request_id = request_id
self.execution_id = execution_id
def fileopen(self=None):
global fileName
global path
path = fd.askopenfilename(title = "Select File", filetypes=( ("Excel files", "*.xlsx"),("All files", "*.*") ) )
fileName = os.path.split(path)[1]
if not fileName:
messagebox.showerror("ERROR - File Not Selected", "A file was not selected to process. Please select a file by double-clicking or select file and press Open button")
else:
file_select_label = Label(root, text=("File Selected: " + fileName), width=75, bg="light blue")
file_select_label.grid(row=7, columnspan=2)
return path
def filesave(self=None):
global save_location
save_location = fd.askdirectory(title = "Select Directory")
if not save_location:
messagebox.showerror("ERROR - Directory Not Selected", "This upload process will build an output file. Please select a folder where the output file can be saved")
else:
file_select_label = Label(root, text=("Output file will be saved: " + save_location), width=75, bg="light blue")
file_select_label.grid(row=8, columnspan=2)
return save_location
def submit(self, path, save_location, request_id, execution_id):
print("FileLogic path: " + self.path)
print("FileLogic save: " + self.save_location)
print("FileLogic request: " + self.request_id)
print("FileLogic execution: " + self.execution_id)
# FileParsing.__init__(request_id)
class FileParsing:
def __init__(self, request_id):
self.request_id = request_id
# self.execution_id_entry = execution_id_entry
print("request id2: " + request_id)
class Application(Frame):
def __init__(self, master):
ttk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
global submit_button
##### Define the Labels ###############
self.request_id_label = Label(root, text="Enter Rebate Request Id:", bg="light blue", bd=2, width=25).grid(row=0, column=0)
self.execution_id_label = Label(root, text="Enter Rebate Execution Id:", bg="light blue", bd=2, width=25).grid(row=1, column=0)
self.blank_label = Label(root, bg="light blue")
####### Define the Entry fields ##################
self.request_id_entry = Entry(root,bg="light gray", bd=2, width=25, textvariable=request_id_entry).grid(row=0, column=1)
self.execution_id_entry = Entry(root, bg="light gray", bd=2, width=25, textvariable=execution_id_entry).grid(row=1, column=1)
###### Define the Buttons ###############
self.submit_button = Button(root, text="Submit", bg="gray", width=17, command= lambda: self.submit_click(path, save_location, request_id, execution_id))
self.submit_button.config(state='disabled')
self.open_file_button = Button(root, text="Select file to process", width = 30, command=FileLogic.fileopen).grid(row=3, column=0)
self.save_location_button = Button(root, text="Select location to save output", width=30, command=FileLogic.filesave).grid(row=4, column=0)
##### Build the Grid ##################
self.blank_label.grid(row=2, column=0)
self.blank_label.grid(row=5, columnspan=2)
self.submit_button.grid(row=6, column=1)
def validate(self, *args):
print("validate")
button_status = self.create_widgets(submit_button)
if request_id_entry.get():
print("normal")
print(button_status)
# self.submit_button.config(state='normal')
else:
print("diabled")
print(submit_button.config)
# self.submit_button.config(state='disabled')
def num_check(self,var):
var = self.var.get()
print(var)
if var.isnumeric():
return True
else:
tkinter.messagebox.showinfo("Error", "Enter Numeric Value")
def submit_click(self, path, save_location, request_id, execution_id):
self.request_id = request_id_entry.get()
self.execution_id = execution_id_entry.get()
a = FileLogic(path, save_location, request_id, execution_id)
FileLogic.submit(a, path, save_location, request_id, execution_id)
root=Tk()
root.title("Rebate Bid Data Upload")
root.geometry("500x200")
root.configure(background="light blue")
request_id_entry = StringVar()
execution_id_entry = StringVar()
request_id_entry.trace("w", Application.validate)
app = Application(root)
root.mainloop()
I am trying to get where the submit button is disabled until all the entry elements and filedialog attributes are complete. Then for the entry fields I am checking to make sure they are numeric and I will want to make sure they are integers.
You are not using textvariable correctly. Also note that you are not keeping a reference of your entry widgets by defining them and calling the grid method on the same line.
def create_widgets(self):
#global submit_button #you don't have to declare global here: submit_button is already an attribute
...
self.request_var = StringVar() #create StringVars for request
self.execution_var = StringVar() #ditto for execution
self.request_id_entry = Entry(root,bg="light gray", bd=2, width=25,textvariable=self.request_var).grid(row=0, column=1) #set the textvariable to the StringVar
self.execution_id_entry = Entry(root, bg="light gray", bd=2, width=25,textvariable=self.execution_var).grid(row=1, column=1)
self.request_var.trace("w",self.validate) #trace changes on StringVar
self.execution_var.trace("w",self.validate)
...
def validate(self, *args):
if self.request_var.get() and self.execution_var.get(): #if both StringVars has content
print("normal")
self.submit_button.config(state='normal')
else:
print("disabled")
self.submit_button.config(state='disabled')

How to add background image to my application in Tkinter?

The code picture needs to fit the screen size perfectly. I saw a bunch of tutorials but nothing seems to work.I tried adding a canvas but it covers half the screen.All my buttons go under the image itself not over it. It's getting on my nerves .
here's my code :
import tkinter as tk
import PIL
from PIL import Image, ImageTk
from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
root = Tk()
w = Label(root, text="Send and receive files easily")
w.config(font=('times', 32))
w.pack()
def create_window():
window = tk.Toplevel(root)
window.geometry("400x400")
tower= PhotoImage(file="D:/icons/tower.png")
towlab=Button(root,image=tower, command=create_window)
towlab.pack()
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("Bifrost v1.0")
self.pack(fill=BOTH, expand=1)
self.img1 = PhotoImage(file="D:/icons/download.png")
self.img2 = PhotoImage(file="D:/icons/upload.png")
sendButton = Button(self, image=self.img2)
sendButton.place(x=305, y=15)
receiveButton = Button(self, image=self.img1)
receiveButton.place(x=355, y=15)
menu = Menu(self.master)
self.master.config(menu=menu)
file = Menu(menu)
file.add_command(label='Exit', command=self.client_exit)
menu.add_cascade(label='File', menu=file)
edit = Menu(menu)
edit.add_command(label='abcd')
menu.add_cascade(label='Edit', menu=edit)
help = Menu(menu)
help.add_command(label='About Us', command=self.about)
menu.add_cascade(label='Help', menu=help)
def callback():
path = filedialog.askopenfilename()
e.delete(0, END) # Remove current text in entry
e.insert(0, path) # Insert the 'path'
# print path
w = Label(root, text="File Path:")
e = Entry(root, text="")
b = Button(root, text="Browse", fg="#a1dbcd", bg="black", command=callback)
w.pack(side=TOP)
e.pack(side=TOP)
b.pack(side=TOP)
def client_exit(self):
exit()
def about(self):
top = Toplevel()
msg = Message(top, text="This is a project developed by Aditi,Sagar and
Suyash as the final year project.",
font=('', '15'))
msg.pack()
top.geometry('200x200')
button = Button(top, text="Okay", command=top.destroy)
button.pack()
top.mainloop()
root.resizable(0,0)
#size of the window
root.geometry("700x400")
app = Window(root)
root.mainloop()
Overlaying elements is tricky. I think this might be approximately what you're looking for. At least it's a start...
import PIL
from PIL import Image, ImageTk
from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
root = Tk()
class Window:
def __init__(self, master=None):
tower = PIL.Image.open("Images/island.png")
master.update()
win_width = int(master.winfo_width())
win_height = int(master.winfo_height())
# Resize the image to the constraints of the root window.
tower = tower.resize((win_width, win_height))
tower_tk = ImageTk.PhotoImage(tower)
# Create a label to hold the background image.
canvas = Canvas(master, width=win_width, height=win_height)
canvas.place(x=0, y=0, anchor='nw')
canvas.create_image(0, 0, image=tower_tk, anchor='nw')
canvas.image = tower_tk
frame = Frame(master)
frame.place(x=win_width, y=win_height, anchor='se')
master.update()
w = Label(master, text="Send and receive files easily", anchor='w')
w.config(font=('times', 32))
w.place(x=0, y=0, anchor='nw')
master.title("Bifrost v1.0")
self.img1 = PhotoImage(file="Images/logo.png")
self.img2 = PhotoImage(file="Images/magnifier.png")
frame.grid_columnconfigure(0, weight=1)
sendButton = Button(frame, image=self.img2)
sendButton.grid(row=0, column=1)
sendButton.image = self.img2
receiveButton = Button(frame, image=self.img1)
receiveButton.grid(row=0, column=2)
receiveButton.image = self.img1
menu = Menu(master)
master.config(menu=menu)
file = Menu(menu)
file.add_command(label='Exit', command=self.client_exit)
menu.add_cascade(label='File', menu=file)
edit = Menu(menu)
edit.add_command(label='abcd')
menu.add_cascade(label='Edit', menu=edit)
help = Menu(menu)
help.add_command(label='About Us', command=self.about)
menu.add_cascade(label='Help', menu=help)
def callback():
path = filedialog.askopenfilename()
e.delete(0, END) # Remove current text in entry
e.insert(0, path) # Insert the 'path'
# print path
w = Label(root, text="File Path:")
e = Entry(root, text="")
b = Button(root, text="Browse", fg="#a1dbcd", bg="black", command=callback)
w.pack(side=TOP)
e.pack(side=TOP)
b.pack(side=TOP)
def client_exit(self):
exit()
def about(self):
message = "This is a project developed by Aditi,Sagar and"
message += "Suyash as the final year project."
messagebox.showinfo("Delete Theme", message)
root.resizable(0,0)
#size of the window
root.geometry("700x400")
app = Window(root)
root.mainloop()

Return Value from TkInter Entry with Button

Python novice, here. I've noticed there are a lot of questions around the topic of returning values from a TkInter function, but none of the solutions seem to solve my issue.
I can successfully print self.e1path to the shell from within getPath.submit, but I cannot return it to the rest of my code. I'm using a print statement outside of the class to test whether I've successfully returned the CSV path.
from tkinter import *
import tkinter as tk
class getPath(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.label1 = tk.Label(self, text="CSV Path").grid(row=0, column=0)
self.e1 = tk.Entry(self, width=50)
self.e1Grid = self.e1.grid(row=0, column=1)
self.browse = tk.Button(self, text='Browse', command=self.getCSV).grid(row=0, column=2)
self.submit = tk.Button(self, text='Submit', command=self.submit).grid(row=1, column=1)
def getCSV(self):
self.fileName = filedialog.askopenfilename( filetypes = (('Comma Separated Values', '*.csv'), ('All Files', '*.*')), title = "Choose a CSV File")
self.e1.insert(10, self.fileName)
def submit(self):
self.e1Path = self.e1.get()
return self.e1Path
app = getPath()
app.mainloop()
print(app)
I figured it out! I needed to add a self.destroy() to the submit function. This stopped the mainloop and let me call on self.e1path outside of the function using app.e1path. New code:
from tkinter import *
import tkinter as tk
class getPath(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.label1 = tk.Label(self, text="CSV Path").grid(row=0, column=0)
self.e1 = tk.Entry(self, width=50)
self.e1Grid = self.e1.grid(row=0, column=1)
self.browse = tk.Button(self, text='Browse', command=self.getCSV).grid(row=0, column=2)
self.submit = tk.Button(self, text='Submit', command=self.submit).grid(row=1, column=1)
def getCSV(self):
self.fileName = filedialog.askopenfilename( filetypes = (('Comma Separated Values', '*.csv'), ('All Files', '*.*')), title = "Choose a CSV File")
self.e1.insert(10, self.fileName)
def submit(self):
self.e1Path = self.e1.get()
self.destroy()
app = getPath()
app.mainloop()
print(app.e1Path)

Resources