I'm new in GUI developing.Here i'hv created two GUI, one for taking photo and another for showing features.so,i'hv used two functions.but i don't know some things.Now i need two kinds of help from you.
1)what is the command for printing float value in GUI(not on console)?
2)How to calculate the value of mean,variance ,s.d. etc from a image and how to pass those values from one function to another function?
import tkinter as tk
from tkinter.filedialog
import askopenfilename
import shutil
import os
from PIL import Image, ImageTk
window = tk.Tk()
window.title(" ")
window.geometry("500x510")
window.configure(background ="lightgreen")
title = tk.Label(text="Click below to choose picture for testing disease....", background = "lightgreen", fg="Brown", font=("", 15))
title.grid()
def feature():
window.destroy()
window1 = tk.Tk()
window1.title(" ")
window1.geometry("650x510")
window1.configure(background="lightgreen")
def exit():
window1.destroy()
#i want to print some features of image e.g. Mean, variance,s.d. Etc.
button = tk.Button(text="Exit", command=exit)
button.grid(column=0, row=9, padx=20, pady=20)
window1.mainloop()
def openphoto():
import cv2
import numpy as np
dirPath = " "
fileList = os.listdir(dirPath)
for fileName in fileList:
os.remove(dirPath + "/" + fileName)
fileName = askopenfilename(initialdir='', title='Select image for analysis ',
filetypes=[('image files', '.jpg')])
dst = " "
shutil.copy(fileName, dst)
#this is the image
Photo = Image.open(fileName)
render = ImageTk.PhotoImage(photo)
img = tk.Label(image=render, height="250", width="500")
img.image = render
img.place(x=0, y=0)
img.grid(column=0, row=1, padx=10, pady = 10)
title.destroy()
button1.destroy()
button2 = tk.Button(text="Analyse Image", command=feature)
button2.grid(column=0, row=2, padx=10, pady = 10)
button1 = tk.Button(text="Get Photo", command = openphoto)
button1.grid(column=0, row=1, padx=10, pady = 10)
window.mainloop()
Okay, I took some more time to look into it.
Concerning the calculation of the values, your previous question did that correct, however the variables needed to be accessible globally. Concerning the displaying of a text, you have to add a tkinter text widget. If you want to add more calculated values, just google for numpy + 'value your want'.
I've taken your code and created a working example, see the code below. Note that I removed some stuff that wasn't neede for the example, so copy the lines you need to your own code. Also check out this reference for the text widget.
Result:
Code:
Note: I created 2 text widgets deliberately, to show 2 ways of implementing multiple texts
import tkinter as tk
from tkinter.filedialog import askopenfilename
import shutil
import os
from PIL import Image, ImageTk
window = tk.Tk()
window.title(" ")
window.geometry("500x510")
window.configure(background ="lightgreen")
title = tk.Label(text="Click below to choose picture for testing disease....", background = "lightgreen", fg="Brown", font=("", 15))
title.grid()
def feature():
window.destroy()
window1 = tk.Tk()
window1.title(" ")
### create a text widget, place it in window1 and insert the text
width_txt = tk.Text(window1, height=2, width=30, fg="RED", background = "lightgreen", relief="flat")
width_txt.grid(column=0, row=0)
width_txt.insert(tk.END, "Width: " + str(width))
height_txt = tk.Text(window1, height=2, width=30, fg="RED", background = "lightgreen", relief="flat")
height_txt.grid(column=0, row=1)
height_txt.insert(tk.END, "Height: " + str(height) + "\nMean: " + str(mean))
window1.geometry("650x510")
window1.configure(background="lightgreen")
def openphoto():
### this line makes the variables accessible everywhere
global width,height, mean
import numpy as np
fileName = askopenfilename(initialdir='', title='Select image for analysis ',
filetypes=[('image files', '.jpg')])
photo = Image.open(fileName)
#### calculate values
height = np.size(photo, 0)
width = np.size(photo, 1)
mean = np.mean(photo)
render = ImageTk.PhotoImage(photo)
img = tk.Label(image=render, height="250", width="500")
img.image = render
img.place(x=0, y=0)
img.grid(column=0, row=1, padx=10, pady = 10)
title.destroy()
button1.destroy()
button2 = tk.Button(text="Analyse Image", command=feature)
button2.grid(column=0, row=2, padx=10, pady = 10)
button1 = tk.Button(text="Get Photo", command = openphoto)
button1.grid(column=0, row=1, padx=10, pady = 10)
window.mainloop()
Related
I was making python gui with tkinter
I wanted to change button's image if I push button
But it doesn't work.(I use config)
with some effort I found it work in main code
but still it doesn't work in fucntion that is connected to button
Here are the codes
from tkinter import *
from PIL import Image, ImageTk
# using by function
def select_precision():
overheal = image_resize((20, 20), "gui_project/item_simulation/overheal.png")
runepage_00.config(image=overheal)
def image_resize(size, link):
image = Image.open(link)
image = image.resize(size, Image.ANTIALIAS)
image = ImageTk.PhotoImage(image)
return image
root = Tk()
root.title()
precision = PhotoImage(file="gui_project/item_simulation/precision.png")
rune00 = PhotoImage(file="gui_project/item_simulation/domination.png")
runepage_precision = Button(root, width=20, height=20,\
image=precision, command=select_precision)
runepage_00 = Button(root, width=20, height=20, image=rune00)
runepage_precision.pack()
runepage_00.pack()
root.mainloop()
but if I change like this, the config works but I don't know why
from tkinter import *
from PIL import Image, ImageTk
def image_resize(size, link):
image = Image.open(link)
image = image.resize(size, Image.ANTIALIAS)
image = ImageTk.PhotoImage(image)
return image
root = Tk()
root.title()
precision = PhotoImage(file="gui_project/item_simulation/precision.png")
rune00 = PhotoImage(file="gui_project/item_simulation/domination.png")
runepage_precision = Button(root, width=20, height=20,\
image=precision, command=select_precision)
runepage_00 = Button(root, width=20, height=20, image=rune00)
# using inside the code
overheal = image_resize((20, 20), "gui_project/item_simulation/overheal.png")
runepage_00.config(image=overheal)
runepage_precision.pack()
runepage_00.pack()
root.mainloop()
to make it short
first was
def select_precision():
overheal = image_resize((20, 20), "gui_project/item_simulation/overheal.png")
runepage_00.config(image=overheal)
runepage_precision = Button(root, width=20, height=20,\
image=precision, command=select_precision)
runepage_00 = Button(root, width=20, height=20, image=rune00)
and second was
runepage_precision = Button(root, width=20, height=20,\
image=precision, command=select_precision)
runepage_00 = Button(root, width=20, height=20, image=rune00)
overheal = image_resize((20, 20), "gui_project/item_simulation/overheal.png")
runepage_00.config(image=overheal)
All of the tutorials I have seen deomonstrate the tkinter filedialog.askopenfilename function by only using the information collected within the function that is linked to the tkinter button. I can pass information in the function, but I would like to pass variables (filepath, images, etc.) outside the function and have them update variables in my GUI.
I have commented out the location I would like to call the variables in main_gui_setup function below. Any help will be appreciated, as it has been very demoralizing not being able to open a file. If this problem persists, my future as a programmer may be limited to creating tic-tac-toe games or instructional videos for Youtube.
from tkinter import *
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog, messagebox
from PIL import ImageTk, Image # was import PIL.Image, PIL.ImageTk
import cv2
def main():
root = Tk()
window1 = Window(root, "X-ray Assist", "Give up")
return None
# can't pass by reference in python
class Window():
n = 0
file_path = ""
img1_info = ""
def __init__(self, root, title, message):
self.root = root
self.root.title(title)
#self.root.geometry(geometry)
self.screen_width = root.winfo_screenwidth()
self.screen_height = root.winfo_screenheight()
#self.root.attributes('-topmost', 1)
# SET APP WINDOW SIZE
scr_size_main = self.scr_size() # create instance of scr_size
self.root.geometry("%dx%d+%d+%d" % (self.root_width, self.root_height, self.root_x, self.root_y))
# CREATE MAIN WINDOW GUI
create_gui = self.main_gui_setup()
self.root.mainloop()
pass
def scr_size(self):
'''Reads monitor size and adjusts GUI frame sizes'''
self.root_width = int(self.screen_width*0.52)
self.root_height = int(self.screen_height*0.9)
self.root_x = int(self.screen_width*0.23)
self.root_y = int(self.screen_height*0.02)
self.img_ht_full = int(self.screen_height*0.82)
self.tools_nb_width = int(self.screen_width*0.22)
self.tools_nb_height = int(self.screen_height*0.48)
self.hist_nb_width = int(self.screen_width*0.22)
self.hist_nb_height = int(self.screen_height*0.23)
def open_image(self):
main_win = ttk.Frame(self.root)
main_win.grid(column=0, row=0)
self.file_path = filedialog.askopenfilename(initialdir='/', title='Open File',
filetypes=(('tif files', '*.tif'), ('all files', '*.*')))
self.file_path_label = ttk.Label(main_win, text=self.file_path)
self.file_path_label.grid(column=0, row=0, columnspan=1, sticky="nw", padx=(5,0), pady=1)
self.img1_8bit = cv2.imread(self.file_path, 0) #, cv2.IMREAD_ANYDEPTH | cv2.IMREAD_GRAYSCALE)
#self.img1_8bit_resize = cv2.resize(self.img1_8bit, (self.img_ht_full, self.img_ht_full)) #, interpolation = cv2.INTER_CUBIC)
#self.img1_height, self.img1_width = self.img1_8bit.shape # not resized for screen
#img1_info = text = f"{self.img1_height} {self.img1_8bit.dtype} {self.img1_16bit.dtype}"
#print(self.img1_width, " x ", self.img1_height, " bitdepth = ", self.img1_8bit.dtype)
#img1_info = ttk.Label
#print(f"{self.img1_height} {self.img1_width} {self.img1_8bit.dtype}")
#img1_info.grid(column=3, row=1, columnspan=1, sticky="w", padx=(5,0), pady=1)
#img = io.imread(main_win.filename) #scikit
self.img1_16bit = cv2.imread(self.file_path, cv2.IMREAD_ANYDEPTH | cv2.IMREAD_GRAYSCALE)
#self.img_canvas = tk.Canvas(self.root, width=self.img_ht_full, height=self.img_ht_full)
#self.img_canvas.grid(column=1, row=2, columnspan=10, rowspan=10, sticky="nw")
#self.img_canvas.image = ImageTk.PhotoImage(image=Image.fromarray(self.img1_8bit_resize))
#self.img_canvas.create_image(0,0, image=self.img_canvas.image, anchor="nw")
# .create_line(x1, y1, x2, y2, fill="color")
#self.img_canvas.create_line((self.img_ht_full/2), 0, (self.img_ht_full/2), (self.img_ht_full), fill="yellow")
#self.img_canvas.create_line(0, (self.img_ht_full/2), (self.img_ht_full), (self.img_ht_full/2), fill="yellow")
def main_gui_setup(self):
main_win = ttk.Frame(self.root)
main_win.grid(column=0, row=0)
image_win = ttk.Frame(main_win, borderwidth=25, relief="groove", width=self.img_ht_full, height=self.img_ht_full)
image_win.grid(column=1, row=2, columnspan=10, rowspan=10, sticky="nw")
toolbar = ttk.Frame(main_win, borderwidth=5) #, width=1100, height=15)
toolbar.grid(column=0, row=0, columnspan=10, rowspan=1, sticky="nw", padx=20)
hist_win = ttk.Frame(main_win, borderwidth=25, relief="groove", width=300, height=200)
panel_info = ttk.Label(main_win, text=f"{self.screen_width} x {self.screen_height}")
panel_info.grid(column=5, row=1, columnspan=1, sticky="e", pady=1)
# SCROLL SLIDER AT BOTTOM
slider = ttk.Scrollbar(main_win, orient="horizontal")
slider.grid(column=1, row=13, columnspan=7, padx=5, pady=5, sticky="ew")
#X-RAY AND DETECTOR SETTINGS - will input these from separate class
kv = ttk.Label(main_win, text="125kV")
kv.grid(column=0, row=2, columnspan=1, padx=15, pady=5)
file_path_label = ttk.Label(main_win, text="No image loaded")
file_path_label.grid(column=1, row=1, columnspan=1, sticky="nw", padx=(5,0), pady=1)
# CREATE BUTTONS
open = ttk.Button(toolbar, text="Open", width=10, command=self.open_image)
open.grid(column=0, row=0)
save = ttk.Button(toolbar, text="Save", width=10)
save.grid(column=1, row=0)
b1 = ttk.Button(toolbar, text="1", width=10)
b1.grid(column=2, row=0)
b2 = ttk.Button(toolbar, text="2", width=10)
b2.grid(column=3, row=0)
pass
main()
You aren't thinking of event driven programming correctly. In event driven programming you have callbacks to the functions you defined. Let's look at your code:
def get_path(self):
...
self.path_label = ...
...
def main_gui_setup(self):
main_win = ttk.Frame(self.root)
main_win.pack()
open = ttk.Button(main_win, text="Open", width=10, command=self.get_path)
open.pack()
# Problematic code:
# main_label = ttk.Label(main_win, self.path_label)
# main_label.pack()
When main_gui_setup is called it creates a frame and a button inside it. When the button is clicked it calls get_path which sets up the path_label variable. The problem that you were facing is that that as soon as you create your button (without waiting for the button to be pressed), you create the label called main_label.
For a simple fix to your problem try this:
def get_path(self):
...
self.file_path = ...
self.path_label = ...
...
def button_callback(self, main_win):
# set up
self.get_path()
# My guess is that you wanted `self.file_path` here instead of `self.path_label`
main_label = ttk.Label(main_win, self.file_path)
main_label.pack()
def main_gui_setup(self):
main_win = ttk.Frame(self.root)
main_win.pack()
# I am using a lambda and passing in `main_win` because you haven't
# assigned it to `self` using `self.main_win = ...`
open = ttk.Button(main_win, text="Open", width=10, command=lambda: self.button_callback(main_win))
open.pack()
I am still confused by what You are trying to accomplish:
from tkinter import Tk, Button, Label, filedialog
class MainWindow(Tk):
def __init__(self):
Tk.__init__(self)
self.open_file_btn = Button(self, text='Open', command=self.open_file)
self.open_file_btn.pack()
self.file_name = None
def open_file(self):
self.file_name = filedialog.askopenfilename()
Label(self, text=self.file_name).pack()
root = MainWindow()
root.mainloop()
I will explain what will happen here! (You can change the .askopenfilename() attributes obviously).
When the program opens the filedialog and You select a file, that file name will now get assigned to self.file_name and that variable can be used anywhere in the class.
also from what I have seen You should learn more about classes and PEP 8
The problem:
I am trying to update the same text widget box from a function that contains some text. Instead a whole new text window appears every time.
Here is my code:
from tkinter import *
import os
#Tkinter graphics
homepage = Tk()
homepage.title("My first GUI")
# set size of window
homepage.geometry('1200x400')
# Add image file
bg = PhotoImage(file = "maxresdefault.png")
# Show image using label
label1 = Label( homepage, image = bg)
label1.place(x = 0, y = 0)
label2 = Label( homepage, text = "Test App")
label2.pack()
# Create Frame
frame1 = Frame(homepage)
frame1.pack()
#button initatiors
def buttonupdate():
S = Scrollbar(homepage)
T = Text(homepage, height=100, width=30)
T.pack()
T.pack(side=RIGHT, fill= Y)
S.pack(side = RIGHT, fill = Y)
S.config(command=T.yview)
T.insert(END, "test")
T.config(yscrollcommand=S.set, state=DISABLED)
# Static buttons
tickets30button = Button(text = "This is button 1", command=buttonupdate)
tickets30button.place(x=0, y=26)
mcibutton = Button(text = "This is button 2")
mcibutton.place(x=0, y=52)
hdebutton = Button(text = "This is button 3")
hdebutton.place(x=0, y=78)
homepage.mainloop()
Here is the result if I click on the first button three times:
Let me know if you have any suggestions that I can try.
Thank you for your time,
I was able to update my text window instead of create a new one, upon each click of a button, thanks to #TheLizzard.
He mentioned to move the section of code that creates the text window outside of the function and keep the section of code that creates the text, inside the function.
Before:
#button initiators
def buttonupdate():
S = Scrollbar(homepage)
T = Text(homepage, height=100, width=30)
T.pack()
T.pack(side=RIGHT, fill= Y)
S.pack(side = RIGHT, fill = Y)
S.config(command=T.yview)
T.insert(END, "test")
T.config(yscrollcommand=S.set, state=DISABLED)
After: (UPDATED)
S = Scrollbar(homepage)
T = Text(homepage, height=100, width=30)
T.pack(side=RIGHT, fill= Y)
S.pack(side = RIGHT, fill = Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set, state=DISABLED)
#button initatiors
def myTicketstatusbutton():
T.delete(1.0,END)
T.insert(END, "test")
I have Created a tkinter UI for some file processing python script. When we choose a directory, then it will return the files in the directory, and then it will takes the each files by using a for loop and it will display 'processed files' for reach iteration. hence the Processed files number have to be change from 0 to the total number of files in the directory.
import os
import time
from tkinter import *
from tkinter import filedialog
import tkinter as tk
root = Tk()
root.title("Demo")
root.geometry('550x300')
root.resizable(width=False, height=False)
def start(userInput,):
e1.configure(text=userInput.get())
print(userInput.get())
ll.destroy()
e1.destroy()
browse_btn.destroy()
st_btn.destroy()
folder_path = userInput.get()
path = folder_path
TEST_IMAGE_PATHS = [f for f in os.listdir(path) if f.endswith('.jpg')]
# print(TEST_IMAGE_PATHS)
Total_No_Files = len(TEST_IMAGE_PATHS)
II_l2_prompt="Total number of files "
II_l2 = Label(root, text=II_l2_prompt, width=22, font=("Arial", 11))
II_l2.place(x=30, y=160, height=25)
II_l3_prompt = str(Total_No_Files)
II_l3 = Label(root, text=II_l3_prompt, width=len(II_l3_prompt), font=("Arial", 11))
II_l3.place(x=240, y=160, height=25)
II_l4_prompt="Processed files "
II_l4 = Label(root, text=II_l4_prompt, width=22, font=("Arial", 11))
II_l4.place(x=30, y=210, height=25)
my_string_var = tk.StringVar()
II_l5_prompt=0
my_string_var.set(II_l5_prompt)
II_l5 = Label(root, textvariable=my_string_var, width=len(str(my_string_var)), font=("Arial", 11))
II_l5.place(x=240, y=210, height=25)
for e in TEST_IMAGE_PATHS:
II_l5_prompt += 1
# time.sleep(2)
my_string_var.set(II_l5_prompt)
def browse(userInput):
File_path = filedialog.askdirectory(title='Select Folder')
if File_path:
File_name = os.path.basename(File_path)
# print(File_name)
e1.delete(0, "end") # delete all the text in the entry
e1.insert(0, File_path)
e1.config(fg='black')
ll = Label(root, text="Path", font=("Arial", 12))
ll.place(x=30, y=110, height=25, width=39)
userInput = StringVar()
e1 = Entry(root,bd=1, textvariable=userInput,width=35, font=("Arial", 12))
e1.insert(0, 'Choose')
e1.config(fg='grey')
e1.bind('<Return>', (lambda event: browse(userInput)))
e1.place(x=80, y=110, height=25)
browse_btn = Button(root, text='Browse',width="10", height=5, bd=0, bg="grey",fg='white', command=(lambda: browse(userInput)))
browse_btn.place(x=420, y=105, height=35)
st_btn = Button(root, text='Start',width="10", height=5, bd=0,bg="grey",fg='white', command=(lambda: start(userInput,)))
st_btn.place(x=150, y=200, height=35)
root.mainloop()
But here the 'Processed files' field is returning the last file number instead of changing the label from 1st file number to last in the directory. How can i solve this issue?
The window will update when it's idle. Here it will queue all changes to the GUI until all processing is done and then update the window after the for loop exits. Therefore you will only see the last state.
You can force root to update with root.update() or root.update_idletasks():
root.update() # Update GUI after removing labels & buttons
for e in TEST_IMAGE_PATHS:
II_l5_prompt += 1
my_string_var.set(II_l5_prompt)
root.update_idletasks() # Update GUI after changing II_l5_prompt
time.sleep(2)
I'm not sure why root.update_idletasks() doesn't work when I use it before the for loop, but root.update() works.
I want to print the mean, height & width of an image in python openCV. Where i used two button (get photo and analysis image) and different GUI,one for getting the photo(def openphoto(): ) and another for printing those features(def feature(): ). But I'm getting error.
N.B. full code is too long.so, i used some part of it.
I've tried it in python openCV.
import tkinter as tk
from tkinter.filedialog import askopenfilename
import shutil
import os
from PIL import Image, ImageTk
window = tk.Tk()
window.title("Dr. Papaya")
window.geometry("500x510")
window.configure(background ="lightgreen")
title = tk.Label(text="Click below to choose picture for testing disease....", background = "lightgreen", fg="Brown", font=("", 15))
title.grid()
def feature():
window.destroy()
window1 = tk.Tk()
window1.title(" ")
window1.geometry("650x510")
window1.configure(background="lightgreen")
def exit():
window1.destroy()
#i want to print here
print("Mean : ",mean)
print("Heigth : ",heigth)
print("Width : ",width)
button = tk.Button(text="Exit", command=exit)
button.grid(column=0, row=9, padx=20, pady=20)
window1.mainloop()
def openphoto():
import cv2
import numpy as np
fileList = os.listdir(dirPath)
for fileName in fileList:
os.remove(dirPath + "/" + fileName)
fileName = askopenfilename(initialdir='', title='Select image for analysis ',
filetypes=[('image files', '.jpg')])
dst = " "
shutil.copy(fileName, dst)
load = Image.open(fileName)
#calculate the mean
mean=np.mean(load)
#calculate the height & width
height = np.size(load, 0)
width = np.size(load, 1)
render = ImageTk.PhotoImage(load)
img = tk.Label(image=render, height="250", width="500")
img.image = render
img.place(x=0, y=0)
img.grid(column=0, row=1, padx=10, pady = 10)
title.destroy()
button1.destroy()
button2 = tk.Button(text="Analyse Image", command=feature)
button2.grid(column=0, row=2, padx=10, pady = 10)
button1 = tk.Button(text="Get Photo", command = openphoto)
button1.grid(column=0, row=1, padx=10, pady = 10)
window.mainloop()
The variables are not in scope when you try to print them. This is an important programming principle so I suggest you read this introduction
You can make the variable global to make the them accessible outside of the function:
def openphoto():
global width, height, mean
[rest of code]