I can't seem to figure out how to update tkinter labels - python

I'm trying to write a script to accept an image, then process the image and put a grid over it. I haven't merged the script that modifies the image yet. I'm trying to put a front end on this, I'm planning on publishing the script in a DnD facebook group for others to use to overlay grids onto their battlemaps. I can't seem to have the GUI update the labels which display the pixel length of the image the user selects.
import tkinter as tk
from tkinter import filedialog
import imageGrid
import sys
from PIL import *
from PIL import Image
root= tk.Tk()
root.withdraw()
iWidth = tk.StringVar()
iHeight = tk.StringVar()
class pinger(tk.Tk):
def __init__(self, parent):
tk.Tk.__init__(self, parent)
self.parent = parent
self.initialize()
def initialize(self):
self.grid()
button = tk.Button(self,text="exit",command=lambda: closeProgram())
button.grid(column=3,row=9)
buttonOpen = tk.Button(self, text="Select an Image", command= lambda: openExplorer()
)
buttonOpen.grid(column=2, row=2)
labelSig = tk.Label(self, text='By Johnathan Keith, 2020. Ver 1.0')
labelSig.grid(column=3,row=10)
labelImgWidth = tk.Label(self, textvariable=iWidth)
labelImgWidth.grid(column=2,row=3)
labelStaticImg= tk.Label(self, text="Width of image, in pixels: ")
labelStaticImg.grid(column=1,row=3)
labelStaticHeight= tk.Label(self, text="Height of image, in pixels: ")
labelStaticHeight.grid(column=3,row=3)
labelImgHeight = tk.Label(self, textvariable=iHeight)
labelImgHeight.grid(column=4,row=3)
labelWidth = tk.Label(self, text='Enter the width of the grid, in pixels.')
labelWidth.grid(column=4,row=2)
labelDisclaim = tk.Label(self, text='Currently only works with jpegs')
labelDisclaim.grid(column=2, row=1)
def openFile(imagefilename):
Img = Image.open(imagefilename)
height, width = Img.size
iHeight.set(height)
iWidth.set(width)
def closeProgram():
app.destroy()
sys.exit()
def openExplorer():
app.filename= filedialog.askopenfilename(initialdir="/", title="Select an Image", filetypes=(("jpeg files", "*.jpg"),("all files", "*.*")))
if app.filename:
print(app.filename)
pinger.openFile(app.filename)
if __name__ == "__main__":
app = pinger(None)
app.title('Image Gridder')
app.minsize(height=680,width=480)
app.mainloop()
I've been searching through other SE questions and none of them seemed to work with the way my code is written. I'm trying to update the StringVar()'s iWidth and iHeight which will eventually allow the user to specify how they want the grid to overlay the image. I've tried moving them all over the code, in and out of the class, and nothing works. Also, StackExchange kinda butchered the indentation, so don't mind that.
Thank you!

It is because you have two instances of Tk(): root and app (pinger). StringVar iWidth and iHeight are within root scope, other widgets are within app scope. So the content of the StringVars are not shown in widgets within app.
You can remove root stuff and only have app as the only instance of Tk():
import tkinter as tk
from tkinter import filedialog
from PIL import Image
class pinger(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.initialize()
def initialize(self):
self.iWidth = tk.StringVar()
self.iHeight = tk.StringVar()
# row 1
labelDisclaim = tk.Label(self, text='Currently only works with jpegs')
labelDisclaim.grid(column=2, row=1)
# row 2
labelWidth = tk.Label(self, text='Enter the width of the grid, in pixels.')
labelWidth.grid(column=4,row=2)
buttonOpen = tk.Button(self, text="Select an Image", command=self.openExplorer)
buttonOpen.grid(column=2, row=2)
# row 3
labelStaticImg= tk.Label(self, text="Width of image, in pixels: ")
labelStaticImg.grid(column=1,row=3)
labelImgWidth = tk.Label(self, textvariable=self.iWidth)
labelImgWidth.grid(column=2,row=3)
labelStaticHeight= tk.Label(self, text="Height of image, in pixels: ")
labelStaticHeight.grid(column=3,row=3)
labelImgHeight = tk.Label(self, textvariable=self.iHeight)
labelImgHeight.grid(column=4,row=3)
# row 9
button = tk.Button(self,text="exit",command=self.closeProgram)
button.grid(column=3,row=9)
# row 10
labelSig = tk.Label(self, text='By Johnathan Keith, 2020. Ver 1.0')
labelSig.grid(column=3,row=10)
def openFile(self, imagefilename):
Img = Image.open(imagefilename)
height, width = Img.size
self.iHeight.set(height)
self.iWidth.set(width)
def closeProgram(self):
self.destroy()
def openExplorer(self):
filename= filedialog.askopenfilename(initialdir="/", title="Select an Image", filetypes=(("jpeg files", "*.jpg"),("all files", "*.*")))
if filename:
print(filename)
self.openFile(filename)
if __name__ == "__main__":
app = pinger()
app.title('Image Gridder')
app.minsize(height=680,width=480)
app.mainloop()

Related

How to resize the button content with the button

I have a program that resizes the buttons when you resize the window but the image doesn't resize with the buttons.
This is my code:
l = Label(window, image=img).grid(row=0, column=0, rowspan=3, sticky='nesw')
con = Frame(window).grid(row=0, column=1, sticky='nesw')
nextImg = PhotoImage(file='nextImg.png')
lastImg = PhotoImage(file='lastImg.png')
ok = PhotoImage(file="ok".png')
nextCam = Button(con, image=nextImg, command=nxt, background='#2B2B2B').grid(row=0, column=1, sticky='nesw')
lastCam = Button(con, image=lastImg, command=lst, background='#2B2B2B').grid(row=2, column=1, sticky='nesw')
takeImg = Button(con, image=ok, command=ok, background='#2B2B2B').grid(row=1, column=1, sticky='nesw')
I expect the output to look like this:
But what it actually does is:
------------------------Edit-----------------------
This needs to work with more than 2 buttons.
Interesting question. PhotoImage does not have a resize method, but you could use a PIL image to get that. If you don't have PIL you need to pip install pillow to get it.
import tkinter as tk
from PIL import Image, ImageTk
class ImageButton(tk.Button):
"""A button that displays an Image and resizes the image as the Button size changes"""
def __init__(self, master=None, image=None, **kwargs):
super().__init__(master, **kwargs)
if not image: return # no image provided; act as a normal Button
if isinstance(image, str):
self.image = Image.open(image)
elif isinstance(image, Image.Image):
self.image = image
else:
raise TypeError("'image' argument must be a PIL.Image or filename")
self.bind("<Configure>", self._on_configure)
def _on_configure(self, event=None):
size = event.width-4, event.height-4
self.photoimage = ImageTk.PhotoImage(self.image.resize(size))
self.config(image=self.photoimage)
### test / demo code: ###
def main():
root = tk.Tk()
root.geometry('200x200')
win = ImageButton(root, image="ON.gif")
win.pack(fill=tk.BOTH, expand=True)
root.mainloop()
if __name__ == '__main__':
main()
Note that you MUST define the initial size of the window for this to work. If you don't then every resize will trigger it to grow some more.

Tkinter "couldn't open "pyimage1": no such file or directory" error when trying to open an image

I have been trying to add a background image to my Interface but I always get the error:
"couldn't open "pyimage1": no such file or directory"
Also I am pretty new to python.
Already tried multiple methods with tkinter and PIL aswell as tkinter's canvas which didn't work either
This is the whole programm:
import tkinter as tk
from PIL import Image, ImageTk
class MainMenu:
def __init__(self, master):
#creating Main Frame and Window
master.title("Interface")
#Image
image = Image.open(r"Images\matrix.jpg")
photo = ImageTk.PhotoImage(image)
self.background_image = tk.PhotoImage(file=photo)
self.background_label = tk.Label(image=self.background_image)
self.background_label.place(x=0,y=0)
self.background_label.img = self.background_image
#Creating Widgets
self.label1 = tk.Label(master, text="Please Enter the text you would
like encrypted: ")
self.entry1 = tk.Text(master, height=5, width=20)
self.button = tk.Button(master, text="Submit", command=self.Submit)
#Adding Widgets to Grid
self.label1.grid(row=0, column=0, padx=5, pady=5)
self.entry1.grid(row=1, column=0, padx=5, pady=5)
self.button.grid(columnspan=2, pady=10)
#Configuration of Widgets and Main window
master.configure(bg="black")
self.button.configure(bg="light blue")
self.label1.configure(bg="black", fg="light blue")
self.entry1.configure(bg="light blue")
def Submit(self):
print("You entered: " + self.entry1.get())
root = tk.Tk()
Mm = MainMenu(root)
root.mainloop()
The main problem would be within these lines I am guessing:
image = Image.open(r"Images\matrix.jpg")
photo = ImageTk.PhotoImage(image)
self.background_image = tk.PhotoImage(file=photo)
self.background_label = tk.Label(image=self.background_image)
self.background_label.place(x=0,y=0)
self.background_label.img = self.background_image
As you can see I am trying to make an Interface or GUI and everything is working fine except the background image.
Try this:
image = Image.open("Images\matrix.jpg")
photo = ImageTk.PhotoImage(image)
#self.background_image = tk.PhotoImage(file=photo) -- Not needed, delete
self.background_label = tk.Label(image=photo)
self.background_label.image = photo
self.background_label.place(x=0,y=0)
#self.background_label.img = self.background_image -- Also not needed, delete
As far as I can tell this simply means you have used 'tk.PhotoImage' twice on a variable.
For example:
item1_image = tk.Label()
image = tk.PhotoImage('image.png')
item1_image.configure(image=tk.PhotoImage(image))
When you're pulling these variables out of different places in a large file, it is hard to keep track of whether 'PhotoImage' is used. I typically use it as early as possible to avoid the image not appearing.

Updating status bar with opened file name

With amazing help of other stackoverflow users I have made this code for reading out some data out of a gcode file and doing some calculations on it. It is almost done and the last 2 things I have problem with are:
1) I would like the status bar update to display message "File [name of the uploaded file] is uploaded" after the gcode file will be uploaded with the button.
2) I would like to make executable for the program so it can be standalone and work on Mac OS and Windows. I have downloaded and installed (I am on mac) pyinstaller and I am performing some actions on my .py file, the end result looks like ready applications but they don't work.
Thank you in advance for help and all the inputs, I am a complete newbie in python but I have already learned so much from you.
This is the sample gcode file for tests: sample GCODE
And this is the code:
from tkinter import *
import re
from tkinter import messagebox
from tkinter import filedialog
# Here, we are creating our class, Window, and inheriting from the Frame
# class. Frame is a class from the tkinter module. (see Lib/tkinter/__init__)
class Window(Frame):
# Define settings upon initialization. Here you can specify
def __init__(self, master=None):
# parameters that you want to send through the Frame class.
Frame.__init__(self, master)
#reference to the master widget, which is the tk window
self.master = master
#with that, we want to then run init_window, which doesn't yet exist
self.init_window()
# Load the gcode file in and extract the filament value
def get_filament_value(self, fileName):
with open(fileName, 'r') as f_gcode:
data = f_gcode.read()
re_value = re.search('filament used = .*? \(([0-9.]+)', data)
if re_value:
return float(re_value.group(1))
else:
return 0.0
def read_gcode(self):
root.fileName = filedialog.askopenfilename(filetypes = (("GCODE files", "*.gcode"), ("All files", "*.*")))
volume = self.get_filament_value(root.fileName)
mass = volume * 1.13
price = mass * 0.175
self.volume_text.set('Volume is {:.2f} cm3'.format(volume))
self.mass_text.set('Mass is {:.2f} g'.format(mass))
self.price_text.set('Price is {:.2f} DKK'.format(price))
def client_exit(self):
exit()
def about_popup(self):
messagebox.showinfo("About", "This software is created by Bartosz Domagalski and helps to find used filament parameters from Sli3er generated GCODE")
#Creation of init_window
def init_window(self):
# changing the title of our master widget
self.master.title("Filament Data")
# allowing the widget to take the full space of the root window
self.pack(fill=BOTH, expand=1)
# creating a menu instance
menu = Menu(self.master)
self.master.config(menu=menu)
# create the file object)
file = Menu(menu)
help = Menu(menu)
# adds a command to the menu option, calling it exit, and the
# command it runs on event is client_exit
file.add_command(label="Exit", command=self.client_exit)
help.add_command(label="About", command=self.about_popup)
#added "file" to our menu
menu.add_cascade(label="File", menu=file)
menu.add_cascade(label="Help", menu=help)
#Creating the labels
l_instruction = Label(self, justify=CENTER, compound=TOP, text="Load GCODE file to find volume, \n weight and price of used filament.")
l_instruction.pack()
#Creating the button
gcodeButton = Button(self, text="Load GCODE", command=self.read_gcode)
gcodeButton.pack()
# gcodeButton.place(x=60, y=50)
#Label of the used filament
l1 = Label(self, text="")
l1.pack()
l2 = Label(self, text="")
l2.pack()
l3 = Label(self, text="")
l3.pack()
self.volume_text = StringVar()
l = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.volume_text)
l.pack()
l4 = Label(self, text="")
l4.pack()
self.mass_text = StringVar()
m = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.mass_text)
m.pack()
l5 = Label(self, text="")
l5.pack()
self.price_text = StringVar()
p = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.price_text)
p.pack()
#status Bar
status = Label(self, text="Waiting for file... ", bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)
# root window created. Here, that would be the only window, but you can later have windows within windows.
root = Tk()
root.resizable(width=False,height=False);
root.geometry("220x300")
#creation of an instance
app = Window(root)
#mainloop
root.mainloop()

Cannot copy the filename browsed into the main program. Where can i write my main function where i have to write my piece of code. Exactly where?

I am new to trying this TKinter . I have to browse files and folders. What i need is to get the pathname of the files and folders i have browsed. i Am not not able to understand where to put my piece of code in this script? . How can i do it? or should i write a seperate . Am stuck in here. I browsed through stack overflow many have problem of getting filenames returned back to their program s with no proper solution. Can anyone help me on this?Advance thanks.
from Tkinter import Tk, RIGHT, BOTH, RAISED,Label
from ttk import Frame, Button, Style
from PIL import Image, ImageTk
import tkFileDialog
import tkMessageBox
import glob
#global root
f1=""
f2=""
def FileBrowser():
img1_path = tkFileDialog.askopenfilename(parent=root,title='Provide the Query Image ')
global f1
f1=img1_path
#print img1_path
def PathBrowser():
img2_path =tkFileDialog.askdirectory(parent=root,title='Provide the path for Training Dataset ')
global f2
f2=img2_path
#print img2_path
def matcher():
imlist=glob.glob(f2)
print imlist
for file in imlist:
print file
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
global root
self.parent.title("Medical CBIR")
self.style = Style()
self.style.theme_use("default")
frame = Frame(self, relief=RAISED, borderwidth=1)
w = Label(self, text="QUERY IMAGE")
w.pack()
style = Style()
style.configure("TFrame", background="#333")
im = Image.open('D:/database/Mixture/1.png')
img = ImageTk.PhotoImage(im)
label1 = Label(self, image=img)
label1.image = img
label1.place(x=155, y=70)
frame.pack(fill=BOTH, expand=1)
self.pack(fill=BOTH, expand=1)
Retrieve_Image=Button(self,text="Retrieve Related Images",command=matcher)
Retrieve_Image.pack(side=RIGHT, padx=5, pady=5)
Training_Image = Button(self, text="Path of Training Images",command=PathBrowser)
Training_Image.pack(side=RIGHT, padx=5, pady=5)
Test_image = Button(self,text="Browse Test_Image",command=FileBrowser)
Test_image.pack(side=RIGHT, padx=5, pady=5)
def main():
global root
root = Tk()
#root.geometry("300x200+300+300")
root.geometry("500x500")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
# Comparison.py(2nd file)
import cv2
import sys
import GUItkinter
img1_path =GUITKinter.FileBrowser()
img2_path =GUITKinter.PathBrowser()
imlist=glob.glob(f2)
for file in imlist:
compare(img1_path,file) #Function to compare images for similarity
#display the retrieved results
Error: Bad window pathname in img1_path =GUITKinter.FileBrowser()
You have to work out the code yourself. But what I'll do is provide you a way how to format your code & how to implement the problem you are having.
import tkFileDialog
from Tkinter import Tk,Button,StringVar,Entry
class MainClass():
def __init__(self,master):
self.parent=master
self.mainfunc()
def mainfunc(self):
self.path_setup = StringVar()
browse=Button(root,text="Browse",command=lambda:self.path_setup.set(tkFileDialog.askopenfilename(filetypes=[("Image File",'.jpg')])))
browse.grid(row=1,column=1,sticky='E')
path_entry = Entry(root, textvariable=self.path_setup,state='disabled')
path_entry.grid(row=1,column=0,sticky='E')
if __name__ == '__main__':
root = Tk()
root.title("My Program")
root.wm_resizable(0,0)
client = MainClass(root)
root.mainloop()
It's a "piece" of code which I was working on. I have formatted it for you.
Hope this gets you going :)

how to set background image to a window using Tkinter python 2.7

I was working on setting the background image and upon that image adding the labels, buttons and all. everything is coming, but not on the background image, its like this:
And my code is:
from Tkinter import Tk, Frame, BOTH
import Tkinter
from PIL import Image, ImageTk
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("PISE")
self.pack(fill=BOTH, expand=1)
root = Tk()
root.geometry("1111x675+300+300")
app = Example(root)
im = Image.open('wood.png')
tkimage = ImageTk.PhotoImage(im)
Tkinter.Label(root,image = tkimage).pack()
custName = StringVar(None)
yourName = Entry(app, textvariable=custName)
yourName.pack()
relStatus = StringVar()
relStatus.set(None)
labelText = StringVar()
labelText.set('Accuracy Level')
label1 = Label(app, textvariable=labelText, height=2)
label1.pack()
radio1 = Radiobutton(app, text='100%', value='1', variable = relStatus, command=beenClicked1).pack()
radio2 = Radiobutton(app, text='50%', value='5', variable = relStatus, command=beenClicked5).pack()
root.mainloop()
How to fit the background image properly?
Thanks in advance!
You should use place() for placing the image & then use grid() (personally i prefer grid) or pack() for other widgets.
from Tkinter import Tk, Frame, BOTH
import Tkinter
from PIL import Image, ImageTk
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("PISE")
self.pack(fill=BOTH, expand=1)
root = Tk()
root.geometry("1111x675+300+300")
app = Example(root)
im = Image.open('Test1.png')
tkimage = ImageTk.PhotoImage(im)
myvar=Tkinter.Label(root,image = tkimage)
myvar.place(x=0, y=0, relwidth=1, relheight=1)
custName = StringVar(None)
yourName = Entry(root, textvariable=custName)
yourName.pack()
relStatus = StringVar()
relStatus.set(None)
labelText = StringVar()
labelText.set('Accuracy Level')
label1 = Label(root, textvariable=labelText, height=2)
label1.pack()
def beenClicked1():
pass
def beenClicked5():
pass
radio1 = Radiobutton(root, text='100%', value='1', variable = relStatus, command=beenClicked1).pack()
radio2 = Radiobutton(root, text='50%', value='5', variable = relStatus, command=beenClicked5).pack()
root.mainloop()
The reason the widgets were not visible was because you were using two different parents ,i.e, app(its an Instance of class Example,so don't use this) and root.

Categories

Resources