Config Label In classes tkinter [duplicate] - python

This question already has answers here:
Tkinter: AttributeError: NoneType object has no attribute <attribute name>
(4 answers)
Closed 11 months ago.
Im trying to develop a GUI to capture images in a new window. In my work i'am trying to pass a directory of the image to be use on future functions, as of now im trying to configure a label to change its text to my image path
import tkinter as tk
from tkinter import *
import cv2
from PIL import Image, ImageTk
from tkinter.filedialog import askopenfilename
import os
from tkinter import messagebox
from pathlib import PosixPath
from numpy import result_type
class CamView():
def __init__(self, parent):
self.parent = parent
self.window = tk.Toplevel(parent)
self.lmain2 = tk.Label(self.window)
self.lmain2.pack()
self.window.protocol("WM_DELETE_WINDOW", self.close)
self.show_frame()
self.multiple()
self.btn2 = tk.Button(self.window,text="Close", command = lambda: self.close())
self.btn2.pack()
def multiple(self):
self.takePicture_button = tk.Button(self.window, text="Capture Signature",command = lambda: [Main.captureImage(self.parent),self.close()])
self.takePicture_button.pack(ipadx=5,ipady=5,pady=5)
def show_frame(self):
imgtk = ImageTk.PhotoImage(image=self.parent.img)
self.lmain2.imgtk = imgtk
self.lmain2.configure(image=imgtk)
def close(self):
self.parent.test_frame = None
self.window.destroy()
root = tk.Tk()
root.bind('<Escape>', lambda e: root.quit())
font_size = 14
window_width = 800
window_height = 400
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
center_x = int(screen_width/2 - window_width / 2)
center_y = int(screen_height/2 - window_height / 2)
root.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')
frame_dirpath = tk.Frame(root)
frame_dirpath.pack(ipadx=5,ipady=5)
class Main(tk.Frame):
def __init__(self, parent):
self.lmain = tk.Label(parent)
self.lmain.pack()
self.test_frame = None
frame = Frame.__init__(self,parent)
a = Label(text='Verify Signatures:').pack(ipadx=5,ipady=5)
self.c = tk.Label(text = "check").pack(ipadx=5,ipady=5)
b = tk.Button(frame, text='CAMERA', command=self.load_window)
b.pack()
self.image1_path_entry = tk.Entry(frame_dirpath, font=font_size,width=25).pack(ipadx = 5, ipady = 5)
width, height = 800, 600
self.cap = cv2.VideoCapture(0)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
self.do_stuff()
def do_stuff(self):
_, frame = self.cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
self.img = Image.fromarray(cv2image)
if self.test_frame != None:
self.test_frame.show_frame()
self.lmain.after(10, self.do_stuff)
def captureImage(self):
image_to_write = self.cap.read()[1]
filetowrite = "D:/Downloads/c.jpeg"
print(str(filetowrite))
cv2.imwrite(str(filetowrite),image_to_write)
self.c.configure(text = filetowrite)
return
def load_window(self):
if self.test_frame == None:
self.test_frame = CamView(self)
control = Main(root)
root.mainloop()
As on the line self.c = tk.Label(text = "check").pack(ipadx=5,ipady=5) im trying to configure this label to the image path on the function when capturing an image. All i get is object is has no attribute

Changed this:
self.c = tk.Label(text = "check").pack(ipadx=5,ipady=5)
to:
self.c = tk.Label(frame, text = "check").pack(ipadx=5,ipady=5)
You did same as tk.Button(frame,

Related

How to display image with upload button in and resize it with window resize (Dynamically)with Tkinter python, I need to add upload button

I need to add upload button so that I can upload the picture and display with this class. Everything working but when I am adding the upload button its giving me some error and my code is not wokring.
import tkinter as tk
from tkinter import *
from PIL import Image, ImageTk
from tkinter import filedialog
class Layout:
def __init__(self,master):
self.master = master
self.rootgeometry()
self.canvas = tk.Canvas(self.master)
self.canvas.pack()
self.background_image = Image.open(self.openfn())
self.image_copy = self.background_image.copy()
self.background = ImageTk.PhotoImage(self.background_image)
self.loadbackground()
def loadbackground(self):
self.label = tk.Label(self.canvas, image = self.background)
self.label.bind('<Configure>',self.resizeimage)
self.label.pack(fill='both', expand='yes')
def openfn(self):
filename = filedialog.askopenfilename(title='open')
return filename
def rootgeometry(self):
x=int(self.master.winfo_screenwidth()*0.7)
y=int(self.master.winfo_screenheight()*0.7)
z = str(x) +'x'+str(y)
self.master.geometry(z)
def resizeimage(self,event):
image = self.image_copy.resize((self.master.winfo_width(),self.master.winfo_height()))
self.image1 = ImageTk.PhotoImage(image)
self.label.config(image = self.image1)
root = tk.Tk()
a = Layout(root)
root.mainloop()
Create the Button widget within the class constructor and bind it with self.loadbackground. Also, you don't need to recreate the Label widget every time instead use label.configure(image=yourimage).
Here is the code:
import tkinter as tk
from tkinter import *
from PIL import Image, ImageTk
from tkinter import filedialog
class Layout:
def __init__(self,master):
self.master = master
self.rootgeometry()
self.button = Button(self.master, text='Upload', command=self.loadbackground)
self.button.pack()
self.canvas = tk.Canvas(self.master)
self.canvas.pack(fill=BOTH, expand=True)
self.background_image = None
self.image_copy = None
self.background = None
self.label = tk.Label(self.canvas)
self.label.pack(fill='both', expand=True)
def loadbackground(self):
self.background_image = Image.open(self.openfn())
self.image_copy = self.background_image.copy()
self.background = ImageTk.PhotoImage(self.background_image.resize((self.canvas.winfo_width(), self.canvas.winfo_height())))
self.label.configure(image=self.background)
self.label.bind('<Configure>',self.resizeimage)
def openfn(self):
filename = filedialog.askopenfilename(title='open')
return filename
def rootgeometry(self):
x=int(self.master.winfo_screenwidth()*0.7)
y=int(self.master.winfo_screenheight()*0.7)
z = str(x) +'x'+str(y)
self.master.geometry(z)
def resizeimage(self,event):
image = self.image_copy.resize((event.width, event.height))
self.image1 = ImageTk.PhotoImage(image)
self.label.config(image = self.image1)
root = tk.Tk()
a = Layout(root)
root.mainloop()

Termination Async call back error in opencv in tkinter gui

I created a master window in tkinter.... then when I press a button on master window it will open another top level window in which I created a canvas and a button....
Canvas for: reading camera frame by frame and show it in tkinter window
Button for: capture the current frame..but in button I used face detection to detect a face when it detects a face I want close the top-level window and go back master window
In master window I have another button to exit the gui(means master.destroy when I press exit) ....but here when I press exit computer is hanging and asking for force close....I am posting my code below
'''
import tkinter
from tkinter import *
import cv2
import PIL.Image, PIL.ImageTk
import time
import os
import numpy as np
class App(object):
def __init__(self,master3):
self.window=Toplevel(master3)
self.window.title("capturing image")
self.window.geometry("{}x{}".format(self.window.winfo_screenwidth(),self.window.winfo_screenheight()))
self.vid = cv2.VideoCapture(0)
#self.width = self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)
#self.height = self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
self.canvas = Canvas(self.window, width = 1000, height = 700)
self.path = os.path.dirname(os.path.abspath(__file__))
self.detector=cv2.CascadeClassifier(self.path+r'\HarrCascade\haarcascade_frontalface.xml')
#self.recognizer = cv2.face.LBPHFaceRecognizer_create()
#self.recognizer.read(self.path+r'\trained_data\trained_file.xml')
self.canvas.pack()
self.canvas.pack()
self.btn_snapshot=Button(self.window, text="Snapshot", width=50,command=self.snap)
self.btn_snapshot.pack(anchor=CENTER, expand=True)
if not self.vid.isOpened():
raise IOError("Unable to open video source")
else:
self.count=0
self.delay=15
self.update()
def g(self):
if self.vid.isOpened():
_,frame = self.vid.read()
self.frame2 = frame
self.count=1
self.vid.release()
cv2.waitKey(1)
cv2.destroyAllWindows()
for i in range(1,5):
cv2.waitKey(1)
master.deiconify()
def snap(self):
self.gray=cv2.cvtColor(self.frame2,cv2.COLOR_BGR2GRAY)
self.faces= self.detector.detectMultiScale(self.gray, scaleFactor=1.2, minNeighbors=5, minSize=(100, 100), flags=cv2.CASCADE_SCALE_IMAGE)
self.no_faces=self.faces.shape[0]
if self.no_faces >= 1:
for(x,y,w,h) in self.faces:
self.g()
cv2.imwrite("face-0.jpg",self.gray)
def update(self):
if self.vid.isOpened():
ret, frame = self.vid.read()
frame1=cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
if ret:
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame1))
self.canvas.create_image(0, 0, image = self.photo, anchor = NW)
else:
pass
if self.count==0:
self.window.after(self.delay, self.update)
else:
pass
else:
pass
def fun():
App(master)
master.withdraw()
def fun1():
master.quit()
master=Tk(screenName=None,baseName=None,className='Tk',useTk=1)
master.title('face recognition system')
master.geometry("{}x{}".format(master.winfo_screenwidth(),master.winfo_screenheight()))
button2 = Button(master,text = 'Test Image',bg = 'black',fg = 'white',font = ('algerian',10),height = 3,width = 20,command=fun)
button3 = Button(master,text = 'exit',bg = 'black',fg = 'white',font = ('algerian',10),height = 3,width = 20,command=fun1)
button2.pack()
button3.pack()
master.mainloop()
'''
thanks in advance for your kind help

Multiple Video Display using Tkinter in Python for GUI design

My task is to display a webcam stream and its black&white stream in two different frames on a single GUI using Tkinter on python. I have seen some examples on google, but they are of images not videos as in the link here. Example of image display in 2 panes on a single GUI
I need exactly the same thing but for the real time video through my webcam.
Initial question:
"I am having issues in displaying multiple (2) windows for displaying video frames in a GUI using Tkinter in python. Please help me with a
code for this task."
The initial question mentioned 2 windows so here's a basic example on how to create multiple windows with tkinter:
#import tkinter as tk
import Tkinter as tk
class MainWindow(tk.Tk):
def __init__(self, *args, **kwargs):
#super().__init__()
tk.Tk.__init__(self)
self.title("This is the MainWindow")
self._is_hidden = False
self.window1 = OtherWindow(self, title="window 1")
self.window2 = OtherWindow(self, title="window 2")
def toggle_hide(self):
if self._is_hidden:
self.iconify()
self.deiconify()
else:
self.withdraw()
self._is_hidden = not self._is_hidden
class OtherWindow(tk.Toplevel):
def __init__(self, master, *args, **kwargs):
#super().__init__(master)
tk.Toplevel.__init__(self, master)
if 'title' in kwargs:
self.title(kwargs['title'])
self.hide_main_button = tk.Button(self, text="Hide/Show MainWindow")
self.hide_main_button['command'] = self.master.toggle_hide
self.hide_main_button.pack()
if __name__ == '__main__':
root = MainWindow()
root.mainloop()
from ttk import *
import Tkinter as tk
from Tkinter import *
import cv2
from PIL import Image, ImageTk
import os
import numpy as np
global last_frame #creating global variable
last_frame = np.zeros((480, 640, 3), dtype=np.uint8)
global last_frame2 #creating global variable
last_frame2 = np.zeros((480, 640, 3), dtype=np.uint8)
global cap
cap = cv2.VideoCapture(1)
def show_vid(): #creating a function
if not cap.isOpened(): #checks for the opening of camera
print("cant open the camera")
flag, frame = cap.read()
frame = cv2.resize(frame,(400,500))
if flag is None:
print "Major error!"
elif flag:
global last_frame
last_frame = frame.copy()
global last_frame2
last_frame2 = frame.copy()
pic = cv2.cvtColor(last_frame, cv2.COLOR_BGR2RGB) #we can change the display color of the frame gray,black&white here
img = Image.fromarray(pic)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_vid)
def show_vid2():
pic2 = cv2.cvtColor(last_frame2, cv2.COLOR_BGR2GRAY)
img2 = Image.fromarray(pic2)
img2tk = ImageTk.PhotoImage(image=img2)
lmain2.img2tk = img2tk
lmain2.configure(image=img2tk)
lmain2.after(10, show_vid2)
if __name__ == '__main__':
root=tk.Tk() #assigning root variable for Tkinter as tk
lmain = tk.Label(master=root)
lmain2 = tk.Label(master=root)
#lmain.Frame= Frame(width=768, height=576)
#framex.grid(column=3,rowspan=2,padx=5, pady=5)
lmain.pack(side = LEFT)
lmain2.pack(side = RIGHT)
root.title("Fire Alarm Detector") #you can give any title
root.geometry("900x700+100+10") #size of window , x-axis, yaxis
exitbutton = Button(root, text='Quit',fg="red",command= root.destroy).pack(side = BOTTOM,)
show_vid()
show_vid2()
root.mainloop() #keeps the application in an infinite loop so it works continuosly
cap.release()
import tkinter
import PIL.Image
import PIL.ImageTk
import cv2
class App:
def __init__(self, window, video_source1, video_source2):
self.window = window
self.window.title("KEC MEDIA PLAYER")
self.video_source1 = video_source1
self.video_source2 = video_source2
self.photo1 = ""
self.photo2 = ""
# open video source
self.vid1 = MyVideoCapture(self.video_source1, self.video_source2)
# Create a canvas that can fit the above video source size
self.canvas1 = tkinter.Canvas(window, width=500, height=500)
self.canvas2 = tkinter.Canvas(window, width=500, height=500)
self.canvas1.pack(padx=5, pady=10, side="left")
self.canvas2.pack(padx=5, pady=60, side="left")
# After it is called once, the update method will be automatically called every delay milliseconds
self.delay = 15
self.update()
self.window.mainloop()
def update(self):
# Get a frame from the video source
ret1, frame1, ret2, frame2 = self.vid1.get_frame
if ret1 and ret2:
self.photo1 = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame1))
self.photo2 = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame2))
self.canvas1.create_image(0, 0, image=self.photo1, anchor=tkinter.NW)
self.canvas2.create_image(0, 0, image=self.photo2, anchor=tkinter.NW)
self.window.after(self.delay, self.update)
class MyVideoCapture:
def __init__(self, video_source1, video_source2):
# Open the video source
self.vid1 = cv2.VideoCapture(video_source1)
self.vid2 = cv2.VideoCapture(video_source2)
if not self.vid1.isOpened():
raise ValueError("Unable to open video source", video_source1)
#property
def get_frame(self):
ret1 = ""
ret2 = ""
if self.vid1.isOpened() and self.vid2.isOpened():
ret1, frame1 = self.vid1.read()
ret2, frame2 = self.vid2.read()
frame1 = cv2.resize(frame1, (500, 500))
frame2 = cv2.resize(frame2, (500, 500))
if ret1 and ret2:
# Return a boolean success flag and the current frame converted to BGR
return ret1, cv2.cvtColor(frame1, cv2.COLOR_BGR2RGB), ret2, cv2.cvtColor(frame2, cv2.COLOR_BGR2RGB)
else:
return ret1, None, ret2, None
else:
return ret1, None, ret2, None
# Release the video source when the object is destroyed
def __del__(self):
if self.vid1.isOpened():
self.vid1.release()
if self.vid2.isOpened():
self.vid2.release()
def callback():
global v1,v2
v1=E1.get()
v2=E2.get()
if v1 == "" or v2 == "":
L3.pack()
return
initial.destroy()
v1 = ""
v2 = ""
initial = tkinter.Tk()
initial.title("KEC MEDIA PLAYER")
L0 = tkinter.Label(initial, text="Enter the full path")
L0.pack()
L1 = tkinter.Label(initial, text="Video 1")
L1.pack()
E1 = tkinter.Entry(initial, bd =5)
E1.pack()
L2 = tkinter.Label(initial, text="Video 2")
L2.pack()
E2 = tkinter.Entry(initial, bd =5)
E2.pack()
B = tkinter.Button(initial, text ="Next", command = callback)
B.pack()
L3 = tkinter.Label(initial, text="Enter both the names")
initial.mainloop()
# Create a window and pass it to the Application object
App(tkinter.Tk(),v1, v2)
This code works under normal circumstances but I haven't handled situations where one video ends and the other is still playing. Also, the audio has not been handled in this code.
I created two canvases in the same window and ran the video as a series of images. I have resized the video to fit a constant canvas size but you can change the canvas size to fit the video if you want.
You can change the source to be from your webcam.

Tkinter Canvas Image Not Displaying Even with Reference saved

So I have this code:
def addTux(self, h,w,g):
global root
cx = h/(2*g)
cy = w/(2*g)
img = Image.open("sprites/tux.png")
img.thumbnail((g,g))
print "The size of the Image is: "
print(img.format, img.size, img.mode)
# img.show()
self.p_sprite = ImageTk.PhotoImage(img)
root.p_sprite = self.p_sprite
self.tux = self.canvas.create_image(cx*g, cy*g, image=self.p_sprite)
c = self.canvas.coords(self.tux)
print c
print c prints coords...
img.show() opens my penguiny thumbnail (when it's not commented out)...
but Tkinter doesn't show squat.
self.canvas.pack() is called later, and I'm saving two references to the PhotoImage just to be double sure it's not garbage collected.
All I get is a white screen.
I'm sure it's a short in the wetware... just not sure where. Any ideas?
All Code below:
app.py:
from Tkinter import *
from PIL import Image, ImageTk
import constants
class Application(Frame):
def addTux(self, h,w,g):
global root
cx = h/(2*g)
cy = w/(2*g)
img = Image.open("sprites/tux.png")
root.img = img
img.thumbnail((g,g))
print "The size of the Image is: "
print(img.format, img.size, img.mode)
img.show()
self.p_sprite = ImageTk.PhotoImage(img)
root.p_sprite = self.p_sprite
self.tux = self.canvas.create_image(cx*g, cy*g, image=self.p_sprite)
self.canvas.pack()
c = self.canvas.coords(self.tux)
print c
def createTiles(self):
h = constants.bounds["y"][1]
w = constants.bounds["x"][1]
g = constants.grid_size
self.grid = []
# for i in range(0,(h/g)):
# # self.grid.append([])
# # print self.grid[i]
# for j in range(0,(w/g)):
# s = self.canvas.create_rectangle(j * g, i*g, (j+1)*g, (i+1)*g, fill="green")
# # self.grid[i].append(s)
self.addTux(h,w,g)
self.canvas.pack()
def createWidgets(self):
global root
self.frame = Frame(root)
self.frame.pack(fill=BOTH, expand=1)
self.canvas=Canvas(self.frame, height=constants.bounds["y"][1]+10, width=constants.bounds["x"][1]+10, background="red")
self.canvas.pack(fill=BOTH, expand=1)
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.createWidgets()
self.createTiles()
print self.p_sprite
root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()
constants.py:
grid_size=40
bounds = {
"x": [0,1000],
"y": [0,720]
}

Tkinter Show webcam view in second window

I am using a webcam view and performing analysis on the images taken in. I wish to introduce a functionality where a window can be summoned and the user can look at the webcam view in a new window, should they desire. However my attempt causes buttons in my main window to swap over to the instance when I open up the new window. What's going wrong?
Here is my (working) example:
import Tkinter as tk
import cv2
from PIL import Image, ImageTk
class CamView():
def __init__(self, parent):
self.parent = parent
self.window = tk.Toplevel(parent)
self.window.protocol("WM_DELETE_WINDOW", self.close)
self.show_frame()
def show_frame(self):
imgtk = ImageTk.PhotoImage(image=self.parent.img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
def close(self):
self.parent.test_frame = None
self.window.destroy()
root = tk.Tk()
root.bind('<Escape>', lambda e: root.quit())
lmain = tk.Label(root)
lmain.pack()
class Main(tk.Frame):
def __init__(self, parent):
self.test_frame = None
frame = tk.Frame.__init__(self,parent)
a = tk.Label(text='hello!').pack()
b = tk.Button(frame, text='open', command=self.load_window)
b.pack()
width, height = 800, 600
self.cap = cv2.VideoCapture(0)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
self.do_stuff()
def do_stuff(self):
_, frame = self.cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
self.img = Image.fromarray(cv2image)
if self.test_frame != None:
self.test_frame.show_frame()
lmain.after(10, self.do_stuff)
def load_window(self):
self.test_frame = CamView(self)
control = Main(root)
root.mainloop()
In my real code, as well as this working example - it seems that when I load the new window, it places the webcam frame in the first window when I don't want it to!
Fixed! I was getting confused because of self.lmain. Here is the working code:
import Tkinter as tk
import cv2
from PIL import Image, ImageTk
class CamView():
def __init__(self, parent):
self.parent = parent
self.window = tk.Toplevel(parent)
self.lmain2 = tk.Label(self.window)
self.lmain2.pack()
self.window.protocol("WM_DELETE_WINDOW", self.close)
self.show_frame()
def show_frame(self):
imgtk = ImageTk.PhotoImage(image=self.parent.img)
self.lmain2.imgtk = imgtk
self.lmain2.configure(image=imgtk)
def close(self):
self.parent.test_frame = None
self.window.destroy()
root = tk.Tk()
root.bind('<Escape>', lambda e: root.quit())
class Main(tk.Frame):
def __init__(self, parent):
self.lmain = tk.Label(parent)
self.lmain.pack()
self.test_frame = None
frame = tk.Frame.__init__(self,parent)
a = tk.Label(text='hello!').pack()
b = tk.Button(frame, text='open', command=self.load_window)
b.pack()
width, height = 800, 600
self.cap = cv2.VideoCapture(0)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
self.do_stuff()
def do_stuff(self):
_, frame = self.cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
self.img = Image.fromarray(cv2image)
if self.test_frame != None:
self.test_frame.show_frame()
self.lmain.after(10, self.do_stuff)
def load_window(self):
if self.test_frame == None:
self.test_frame = CamView(self)
control = Main(root)
root.mainloop()

Categories

Resources