Note that there are some explanatory texts on larger screens.

plurals
  1. POTkinter nested mainloop
    text
    copied!<p>I am writing a videoplayer with <strong>tkinter/python</strong>, so basically I have a GUI that can play a video. Now, I would like to implement a stop button, meaning that I would have a <code>mainloop()</code> for the GUI, and another nested <code>mainloop()</code> to play/stop the video and return to the GUI startup window. <a href="http://www.pythonware.com/library/tkinter/introduction/x9374-event-processing.htm" rel="nofollow">Here</a>, it is said:</p> <blockquote> <p>Event loops can be nested; it's ok to call mainloop from within an event handler.</p> </blockquote> <p>However, I do not understand how to implement this nesting. Can someone please provide me with a simple example of such a script?</p> <h2>EDIT</h2> <p>Here is a working version of my code, since it seems that I am doing something exotic. Of course, I am a newbie, so it may be that I am mistaken about the necessity to have a nested mainloop.</p> <pre><code>#!/usr/bin/python import numpy as np from multiprocessing import Process, Queue import cv2 import cv2.cv as cv from PIL import Image, ImageTk import Tkinter as tk def image_capture(queue): vidFile = cv2.VideoCapture(0) while True: flag, frame=vidFile.read() frame = cv2.cvtColor(frame,cv2.cv.CV_BGR2RGB) queue.put(frame) cv2.waitKey(10) def update_all(root, imagelabel, queue, process, var): if var.get()==True: im = queue.get() a = Image.fromarray(im) b = ImageTk.PhotoImage(image=a) imagelabel.configure(image=b) imagelabel._image_cache = b # avoid garbage collection root.update() root.after(0, func=lambda: update_all(root, imagelabel, queue, process, var)) else: print var.get() root.quit() def playvideo(root, imagelabel, queue, var): print 'beginning' p = Process(target=image_capture, args=(task,)) p.start() update_all(root, imagelabel, queue, p, var) print 'entering nested mainloop' root.mainloop() p.terminate() if var.get()==False: im = ImageTk.PhotoImage(file='logo.png') imagelabel.configure(image=im) imagelabel._image_cache = im # avoid garbage collection root.update() var.set(True) print 'finishing' if __name__ == '__main__': #initialize multiprocessing task = Queue() #GUI of root window root = tk.Tk() #the image container image_label = tk.Label(master=root) image_label.grid(column=0, row=0, columnspan=2, rowspan=1) #fill label with image until video is loaded bg_im = ImageTk.PhotoImage(file='logo.png') image_label['image'] = bg_im #frame for buttons button_frame = tk.Frame(root) button_frame.grid(column=0, row=1, columnspan=1) #load video button and a switch to wait for the videopath to be chosen load_button = tk.Button(master=button_frame, text='Load video',command=lambda: playvideo(root, image_label, task, switch)) load_button.grid(column=0, row=0, sticky='ew') #Stop button switch = tk.BooleanVar(master=root, value=True, name='switch') stop_button = tk.Button(master=button_frame, text='Stop',command=lambda: switch.set(False)) stop_button.grid(column=0, row=1, sticky='ew') #quit button quit_button = tk.Button(master=button_frame, text='Quit',command=root.destroy) quit_button.grid(column=0, row=2, sticky='ew') root.mainloop() </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload