Python Forum

Full Version: main lop in python tkinter
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have some code like this in my tk program..
       root = tk.Tk()

     # (code like entry boxes, labels, functions, etc.)

      root.mainloop()     # the last statement
Specifically I want to continually display my webcam and also to be able to use the buttons, labels, and etc.

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()
 
    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
    # Display the resulting frame
    cv2.imshow('frame',gray)
    if cv2.waitKey(1) ==27:
        break
1. What is the function of root.mainloop() ? Is this a never ending loop?
2. How do I insert the other code in this loop that gets called repeatedly?
From educba.com
Quote:Root. mainloop() is simply a method in the main window that executes what we wish to execute in an application (lets Tkinter to start running the application). As the name implies it will loop forever until the user exits the window or waits for any events from the user. The mainloop automatically receives events from the window system and deliver them to the application widgets. This gets quit when we click on the close button of the title bar. So, any code after this mainloop() method will not run.

When a GUI is gets started with the mainloop() a method call, Tkinter python automatically initiates an infinite loop named as an event loop. So, after this article, we will be able to use all the widgets to develop an application in Python. Different widgets are Combo box, button, label, Check button, Message Box, Images, and Icons.

For continuous calling of code in mainloop have a look at tkinters after method
This is not mine. I got it Here
import cv2
import tkinter as tk
from PIL import Image, ImageTk

class MainWindow():
	def __init__(self, window, cap):
		self.window = window
		self.cap = cap
		self.width = self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)
		self.height = self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
		self.interval = 20 # Interval in ms to get the latest frame
		# Create canvas for image
		self.canvas = tk.Canvas(self.window, width=self.width, height=self.height)
		self.canvas.grid(row=0, column=0)
		# Update image on canvas
		self.update_image()

	def update_image(self):
		# Get the latest frame and convert image format
		self.image = cv2.cvtColor(self.cap.read()[1], cv2.COLOR_BGR2RGB) # to RGB
		self.image = Image.fromarray(self.image) # to PIL format
		self.image = ImageTk.PhotoImage(self.image) # to ImageTk format
		# Update image
		self.canvas.create_image(0, 0, anchor=tk.NW, image=self.image)
		# Repeat every 'interval' ms
		self.window.after(self.interval, self.update_image)
if __name__ == "__main__":
	root = tk.Tk()
	MainWindow(root, cv2.VideoCapture(0))
	root.mainloop()

	while(True):
		# Capture frame-by-frame
		ret, frame = cap.read()
	  
		# Our operations on the frame come here
		gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
	  
		# Display the resulting frame
		cv2.imshow('frame',gray)
		if cv2.waitKey(1) ==27:
			break
I am trying to do what the above code does, I think. I have a hard time following the code. Here is what I want..
In the snippit below, I would like to see "test" printed out every 10 milliseconds.
I don't think I am using the after properly. What should I do?



def PrintIt()
   print ("test")

root = tk.Tk()
button1 = tk.button(bla bla......

root.after(10, PrintIt)
root.mainloop()
Maybe like this
import tkinter as tk
def print_it():
    print('Test print')
    root.after(100, print_it)


root = tk.Tk()
print_it()
root.mainloop()
I don't understand how this works but it does.

In the above, it seems like the function is calling itself??
Maybe some day I will understand

Thanks, now my real code works
The function is not calling itself. That would quickly run into the maximum recursion limit and the program would crash. Instead print_it() is telling root to call print_it() 100 milliseconds from now.

The reason your implementation didn't work is because after() only schedules a function to run once. Your program called PrintIt() 10 milliseconds after the it root.after() call, and nobody ever scheduled it to run again.