use threading in tkinter





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







-2















I have two class and use tkinter demo.



class App:
def __init__(self, window, window_title, video_source=0):
self.window = window
self.window.title(window_title)
self.video_source = video_source

# open video source (by default this will try to open the computer webcam)
self.vid = MyVideoCapture(self.video_source)

# Create a canvas that can fit the above video source size
self.canvas = tkinter.Canvas(window).place(x=50, y=0)

# set plot parameter
self.fig = Figure(figsize=(7, 4), dpi=100)
self.fresh = FigureCanvasTkAgg(self.fig, master=self.window)
self.ax1 = self.fig.add_subplot(211)
self.ax2 = self.fig.add_subplot(212)

self.fresh.get_tk_widget().place(x=700, y=0)
self.window.geometry('1500x550')

# Camera thread
self.photo = None
self.delay = 15
self.t = threading.Thread(target=self.update, args=())
self.t.setDaemon(True)
self.t.start()

def refresh(self, data):
sample_track = pd.read_csv('/home/share/sample_track.csv')
x = [i for i in range(len(sample_track))]
y = sample_track['0']
xdata = [i for i in range(len(data))]
ydata = data
self.ax1.plot(x, y, 'bo--')
self.ax2.plot(xdata, ydata, 'ro--')
self.fresh.draw()

def update(self):
# Get a frame from the video source
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=tkinter.NW)
self.window.after(self.delay, self.update)

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

def get_frame(self):
if self.vid.isOpened():
self.ret, frame = self.vid.read()
if self.ret:
# Return a boolean success flag and the current frame converted to BGR
return self.ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
else:
return self.ret, None

if __name__ == '__main__':
win = tkinter.Tk()
panel = App(win, "Dance")
value =
for i in range(15):
value.append(np.random.randint(0, 800))
panel.refresh(data=value)
time.sleep(0.1)
win.mainloop()


I want to start the Webcam and refresh the figure at the same time.
I tried to use the thread but still failed.
The following error occurred:




  • RuntimeError: main thread is not in main loop

  • AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'


How can I solve it?










share|improve this question























  • If you use after(), you do not need to use thread. Or use loop in update() instead of after().

    – acw1668
    Jan 3 at 9:45











  • Possible duplicate of How do you run your own code alongside Tkinter's event loop?

    – stovfl
    Jan 3 at 10:22


















-2















I have two class and use tkinter demo.



class App:
def __init__(self, window, window_title, video_source=0):
self.window = window
self.window.title(window_title)
self.video_source = video_source

# open video source (by default this will try to open the computer webcam)
self.vid = MyVideoCapture(self.video_source)

# Create a canvas that can fit the above video source size
self.canvas = tkinter.Canvas(window).place(x=50, y=0)

# set plot parameter
self.fig = Figure(figsize=(7, 4), dpi=100)
self.fresh = FigureCanvasTkAgg(self.fig, master=self.window)
self.ax1 = self.fig.add_subplot(211)
self.ax2 = self.fig.add_subplot(212)

self.fresh.get_tk_widget().place(x=700, y=0)
self.window.geometry('1500x550')

# Camera thread
self.photo = None
self.delay = 15
self.t = threading.Thread(target=self.update, args=())
self.t.setDaemon(True)
self.t.start()

def refresh(self, data):
sample_track = pd.read_csv('/home/share/sample_track.csv')
x = [i for i in range(len(sample_track))]
y = sample_track['0']
xdata = [i for i in range(len(data))]
ydata = data
self.ax1.plot(x, y, 'bo--')
self.ax2.plot(xdata, ydata, 'ro--')
self.fresh.draw()

def update(self):
# Get a frame from the video source
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=tkinter.NW)
self.window.after(self.delay, self.update)

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

def get_frame(self):
if self.vid.isOpened():
self.ret, frame = self.vid.read()
if self.ret:
# Return a boolean success flag and the current frame converted to BGR
return self.ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
else:
return self.ret, None

if __name__ == '__main__':
win = tkinter.Tk()
panel = App(win, "Dance")
value =
for i in range(15):
value.append(np.random.randint(0, 800))
panel.refresh(data=value)
time.sleep(0.1)
win.mainloop()


I want to start the Webcam and refresh the figure at the same time.
I tried to use the thread but still failed.
The following error occurred:




  • RuntimeError: main thread is not in main loop

  • AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'


How can I solve it?










share|improve this question























  • If you use after(), you do not need to use thread. Or use loop in update() instead of after().

    – acw1668
    Jan 3 at 9:45











  • Possible duplicate of How do you run your own code alongside Tkinter's event loop?

    – stovfl
    Jan 3 at 10:22














-2












-2








-2








I have two class and use tkinter demo.



class App:
def __init__(self, window, window_title, video_source=0):
self.window = window
self.window.title(window_title)
self.video_source = video_source

# open video source (by default this will try to open the computer webcam)
self.vid = MyVideoCapture(self.video_source)

# Create a canvas that can fit the above video source size
self.canvas = tkinter.Canvas(window).place(x=50, y=0)

# set plot parameter
self.fig = Figure(figsize=(7, 4), dpi=100)
self.fresh = FigureCanvasTkAgg(self.fig, master=self.window)
self.ax1 = self.fig.add_subplot(211)
self.ax2 = self.fig.add_subplot(212)

self.fresh.get_tk_widget().place(x=700, y=0)
self.window.geometry('1500x550')

# Camera thread
self.photo = None
self.delay = 15
self.t = threading.Thread(target=self.update, args=())
self.t.setDaemon(True)
self.t.start()

def refresh(self, data):
sample_track = pd.read_csv('/home/share/sample_track.csv')
x = [i for i in range(len(sample_track))]
y = sample_track['0']
xdata = [i for i in range(len(data))]
ydata = data
self.ax1.plot(x, y, 'bo--')
self.ax2.plot(xdata, ydata, 'ro--')
self.fresh.draw()

def update(self):
# Get a frame from the video source
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=tkinter.NW)
self.window.after(self.delay, self.update)

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

def get_frame(self):
if self.vid.isOpened():
self.ret, frame = self.vid.read()
if self.ret:
# Return a boolean success flag and the current frame converted to BGR
return self.ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
else:
return self.ret, None

if __name__ == '__main__':
win = tkinter.Tk()
panel = App(win, "Dance")
value =
for i in range(15):
value.append(np.random.randint(0, 800))
panel.refresh(data=value)
time.sleep(0.1)
win.mainloop()


I want to start the Webcam and refresh the figure at the same time.
I tried to use the thread but still failed.
The following error occurred:




  • RuntimeError: main thread is not in main loop

  • AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'


How can I solve it?










share|improve this question














I have two class and use tkinter demo.



class App:
def __init__(self, window, window_title, video_source=0):
self.window = window
self.window.title(window_title)
self.video_source = video_source

# open video source (by default this will try to open the computer webcam)
self.vid = MyVideoCapture(self.video_source)

# Create a canvas that can fit the above video source size
self.canvas = tkinter.Canvas(window).place(x=50, y=0)

# set plot parameter
self.fig = Figure(figsize=(7, 4), dpi=100)
self.fresh = FigureCanvasTkAgg(self.fig, master=self.window)
self.ax1 = self.fig.add_subplot(211)
self.ax2 = self.fig.add_subplot(212)

self.fresh.get_tk_widget().place(x=700, y=0)
self.window.geometry('1500x550')

# Camera thread
self.photo = None
self.delay = 15
self.t = threading.Thread(target=self.update, args=())
self.t.setDaemon(True)
self.t.start()

def refresh(self, data):
sample_track = pd.read_csv('/home/share/sample_track.csv')
x = [i for i in range(len(sample_track))]
y = sample_track['0']
xdata = [i for i in range(len(data))]
ydata = data
self.ax1.plot(x, y, 'bo--')
self.ax2.plot(xdata, ydata, 'ro--')
self.fresh.draw()

def update(self):
# Get a frame from the video source
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=tkinter.NW)
self.window.after(self.delay, self.update)

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

def get_frame(self):
if self.vid.isOpened():
self.ret, frame = self.vid.read()
if self.ret:
# Return a boolean success flag and the current frame converted to BGR
return self.ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
else:
return self.ret, None

if __name__ == '__main__':
win = tkinter.Tk()
panel = App(win, "Dance")
value =
for i in range(15):
value.append(np.random.randint(0, 800))
panel.refresh(data=value)
time.sleep(0.1)
win.mainloop()


I want to start the Webcam and refresh the figure at the same time.
I tried to use the thread but still failed.
The following error occurred:




  • RuntimeError: main thread is not in main loop

  • AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'


How can I solve it?







python matplotlib tkinter






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 3 at 9:32









vincentlaivincentlai

1327




1327













  • If you use after(), you do not need to use thread. Or use loop in update() instead of after().

    – acw1668
    Jan 3 at 9:45











  • Possible duplicate of How do you run your own code alongside Tkinter's event loop?

    – stovfl
    Jan 3 at 10:22



















  • If you use after(), you do not need to use thread. Or use loop in update() instead of after().

    – acw1668
    Jan 3 at 9:45











  • Possible duplicate of How do you run your own code alongside Tkinter's event loop?

    – stovfl
    Jan 3 at 10:22

















If you use after(), you do not need to use thread. Or use loop in update() instead of after().

– acw1668
Jan 3 at 9:45





If you use after(), you do not need to use thread. Or use loop in update() instead of after().

– acw1668
Jan 3 at 9:45













Possible duplicate of How do you run your own code alongside Tkinter's event loop?

– stovfl
Jan 3 at 10:22





Possible duplicate of How do you run your own code alongside Tkinter's event loop?

– stovfl
Jan 3 at 10:22












1 Answer
1






active

oldest

votes


















1














Here is a working tkinter camera taken straight from here (found by a quick search for 'tkinter camera'):



import tkinter
import cv2
import PIL.Image, PIL.ImageTk
import time

class App:
def __init__(self, window, window_title, video_source=0):
self.window = window
self.window.title(window_title)
self.video_source = video_source

# open video source (by default this will try to open the computer webcam)
self.vid = MyVideoCapture(self.video_source)

# Create a canvas that can fit the above video source size
self.canvas = tkinter.Canvas(window, width = self.vid.width, height = self.vid.height)
self.canvas.pack()

# Button that lets the user take a snapshot
self.btn_snapshot=tkinter.Button(window, text="Snapshot", width=50, command=self.snapshot)
self.btn_snapshot.pack(anchor=tkinter.CENTER, expand=True)

# After it is called once, the update method will be automatically called every delay milliseconds
self.delay = 15
self.update()

self.window.mainloop()

def snapshot(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()

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

def update(self):
# Get a frame from the video source
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 = tkinter.NW)

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


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

# Get video source width and height
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 a boolean success flag and the current frame converted to BGR
return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
else:
return (ret, None)
else:
return (ret, None)

# Release the video source when the object is destroyed
def __del__(self):
if self.vid.isOpened():
self.vid.release()

# Create a window and pass it to the Application object
App(tkinter.Tk(), "Tkinter and OpenCV")





share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54019524%2fuse-threading-in-tkinter%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Here is a working tkinter camera taken straight from here (found by a quick search for 'tkinter camera'):



    import tkinter
    import cv2
    import PIL.Image, PIL.ImageTk
    import time

    class App:
    def __init__(self, window, window_title, video_source=0):
    self.window = window
    self.window.title(window_title)
    self.video_source = video_source

    # open video source (by default this will try to open the computer webcam)
    self.vid = MyVideoCapture(self.video_source)

    # Create a canvas that can fit the above video source size
    self.canvas = tkinter.Canvas(window, width = self.vid.width, height = self.vid.height)
    self.canvas.pack()

    # Button that lets the user take a snapshot
    self.btn_snapshot=tkinter.Button(window, text="Snapshot", width=50, command=self.snapshot)
    self.btn_snapshot.pack(anchor=tkinter.CENTER, expand=True)

    # After it is called once, the update method will be automatically called every delay milliseconds
    self.delay = 15
    self.update()

    self.window.mainloop()

    def snapshot(self):
    # Get a frame from the video source
    ret, frame = self.vid.get_frame()

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

    def update(self):
    # Get a frame from the video source
    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 = tkinter.NW)

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


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

    # Get video source width and height
    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 a boolean success flag and the current frame converted to BGR
    return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    else:
    return (ret, None)
    else:
    return (ret, None)

    # Release the video source when the object is destroyed
    def __del__(self):
    if self.vid.isOpened():
    self.vid.release()

    # Create a window and pass it to the Application object
    App(tkinter.Tk(), "Tkinter and OpenCV")





    share|improve this answer




























      1














      Here is a working tkinter camera taken straight from here (found by a quick search for 'tkinter camera'):



      import tkinter
      import cv2
      import PIL.Image, PIL.ImageTk
      import time

      class App:
      def __init__(self, window, window_title, video_source=0):
      self.window = window
      self.window.title(window_title)
      self.video_source = video_source

      # open video source (by default this will try to open the computer webcam)
      self.vid = MyVideoCapture(self.video_source)

      # Create a canvas that can fit the above video source size
      self.canvas = tkinter.Canvas(window, width = self.vid.width, height = self.vid.height)
      self.canvas.pack()

      # Button that lets the user take a snapshot
      self.btn_snapshot=tkinter.Button(window, text="Snapshot", width=50, command=self.snapshot)
      self.btn_snapshot.pack(anchor=tkinter.CENTER, expand=True)

      # After it is called once, the update method will be automatically called every delay milliseconds
      self.delay = 15
      self.update()

      self.window.mainloop()

      def snapshot(self):
      # Get a frame from the video source
      ret, frame = self.vid.get_frame()

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

      def update(self):
      # Get a frame from the video source
      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 = tkinter.NW)

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


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

      # Get video source width and height
      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 a boolean success flag and the current frame converted to BGR
      return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
      else:
      return (ret, None)
      else:
      return (ret, None)

      # Release the video source when the object is destroyed
      def __del__(self):
      if self.vid.isOpened():
      self.vid.release()

      # Create a window and pass it to the Application object
      App(tkinter.Tk(), "Tkinter and OpenCV")





      share|improve this answer


























        1












        1








        1







        Here is a working tkinter camera taken straight from here (found by a quick search for 'tkinter camera'):



        import tkinter
        import cv2
        import PIL.Image, PIL.ImageTk
        import time

        class App:
        def __init__(self, window, window_title, video_source=0):
        self.window = window
        self.window.title(window_title)
        self.video_source = video_source

        # open video source (by default this will try to open the computer webcam)
        self.vid = MyVideoCapture(self.video_source)

        # Create a canvas that can fit the above video source size
        self.canvas = tkinter.Canvas(window, width = self.vid.width, height = self.vid.height)
        self.canvas.pack()

        # Button that lets the user take a snapshot
        self.btn_snapshot=tkinter.Button(window, text="Snapshot", width=50, command=self.snapshot)
        self.btn_snapshot.pack(anchor=tkinter.CENTER, expand=True)

        # After it is called once, the update method will be automatically called every delay milliseconds
        self.delay = 15
        self.update()

        self.window.mainloop()

        def snapshot(self):
        # Get a frame from the video source
        ret, frame = self.vid.get_frame()

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

        def update(self):
        # Get a frame from the video source
        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 = tkinter.NW)

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


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

        # Get video source width and height
        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 a boolean success flag and the current frame converted to BGR
        return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
        else:
        return (ret, None)
        else:
        return (ret, None)

        # Release the video source when the object is destroyed
        def __del__(self):
        if self.vid.isOpened():
        self.vid.release()

        # Create a window and pass it to the Application object
        App(tkinter.Tk(), "Tkinter and OpenCV")





        share|improve this answer













        Here is a working tkinter camera taken straight from here (found by a quick search for 'tkinter camera'):



        import tkinter
        import cv2
        import PIL.Image, PIL.ImageTk
        import time

        class App:
        def __init__(self, window, window_title, video_source=0):
        self.window = window
        self.window.title(window_title)
        self.video_source = video_source

        # open video source (by default this will try to open the computer webcam)
        self.vid = MyVideoCapture(self.video_source)

        # Create a canvas that can fit the above video source size
        self.canvas = tkinter.Canvas(window, width = self.vid.width, height = self.vid.height)
        self.canvas.pack()

        # Button that lets the user take a snapshot
        self.btn_snapshot=tkinter.Button(window, text="Snapshot", width=50, command=self.snapshot)
        self.btn_snapshot.pack(anchor=tkinter.CENTER, expand=True)

        # After it is called once, the update method will be automatically called every delay milliseconds
        self.delay = 15
        self.update()

        self.window.mainloop()

        def snapshot(self):
        # Get a frame from the video source
        ret, frame = self.vid.get_frame()

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

        def update(self):
        # Get a frame from the video source
        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 = tkinter.NW)

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


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

        # Get video source width and height
        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 a boolean success flag and the current frame converted to BGR
        return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
        else:
        return (ret, None)
        else:
        return (ret, None)

        # Release the video source when the object is destroyed
        def __del__(self):
        if self.vid.isOpened():
        self.vid.release()

        # Create a window and pass it to the Application object
        App(tkinter.Tk(), "Tkinter and OpenCV")






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 3 at 18:28









        Minion JimMinion Jim

        272214




        272214
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54019524%2fuse-threading-in-tkinter%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith