0

I am trying to create different radio buttons for different methods of uploading an image. I created a function for running a camera and showcasing it with a button to take a picture. Whenever I call this function it works. But when I try to call it inside tk.radiobutton I get the following error.

_tkinter.TclError: image "pyimage77" doesn't exist

Here is my code. I try to create a function called camerachoice which creates a window for the camera. #

import tkinter as tk
from tkinter import filedialog
import cv2
import PIL.Image, PIL.ImageTk
import time
def camerachoice():
    class App:
        def __init__(self, window, window_title, video_source=0):
            self.window = window        
            self.window.title(window_title)
            self.video_source = video_source
            self.vid = MyVideoCapture(self.video_source)
            self.canvas = tk.Canvas(window, width = self.vid.width, height = self.vid.height)
            self.canvas.pack()
            self.btn_snapshot=tk.Button(window, text="Snapshot", width=50, command=self.snapshot)
            self.btn_snapshot.pack(anchor=tk.CENTER, expand=True)                       
            self.delay = 15
            self.update()


            self.window.mainloop()

        def snapshot(self):

            ret, frame = self.vid.get_frame()

            if ret:
                #cv2.imwrite("frame-" + time.strftime("%d-%m-%Y-%H-%M- br%S") + ".jpg", cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
                cv2.imwrite("cancercheck.jpg", cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))


        def update(self):

            ret, frame = self.vid.get_frame()

            if ret:

                self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
                self.canvas.create_image(0, 0, image = self.photo, anchor = tk.NW)

            self.window.after(self.delay, self.update)


    class MyVideoCapture:
        def __init__(self, video_source=0):
            self.vid = cv2.VideoCapture(video_source)
            if not self.vid.isOpened():     
                raise ValueError("Unable to open video source", video_source)

            self.width = self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)
            self.height = self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)

        def get_frame(self):
            if self.vid.isOpened():
                ret, frame = self.vid.read()
                if ret:
                    return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
                else:
                    return (ret, None)
            else:
                return (ret, None)

        def __del__(self):

            if self.vid.isOpened():
                self.vid.release()

#App()
    App(tk.Tk(), "Tkinter and OpenCV")



root = tk.Tk()
v = tk.IntVar()
tk.Label(root, 
        text="""Choose method:""",
        justify = tk.LEFT,
        padx = 20).pack()

tk.Radiobutton(root, 
               text="Camera",
               padx = 20, 
               variable=v, 
               command=camerachoice(),
               value=2,
               ).pack(anchor=tk.W)
    

root.mainloop()
mdansfo
  • 11
  • 4
  • Add `master=self.canvas` to the `PIL.ImageTk.PhotoImage(...)` or use `tk.Toplevel()` instead of opening a new `tk.Tk()` window. Also you need to change `command=camerachoice()` to just `command=camerachoice`. – TheLizzard Jun 09 '21 at 20:52
  • Thank you so much, tk.Toplevel() worked. If you don't mind me asking. Why is it when we use commands with Tkinter we don't end them with ()? – mdansfo Jun 09 '21 at 21:00
  • Look at [this](https://stackoverflow.com/questions/5767228/why-is-the-command-bound-to-a-button-or-event-executed-when-declared). It first calls the function then setts `command` to whatever the function returns (which is `None`). – TheLizzard Jun 09 '21 at 21:01
  • Thank you so much! – mdansfo Jun 10 '21 at 01:06

0 Answers0