【问题标题】:How can I get elements in Tkinter windows to fill the frame?如何在 Tkinter 窗口中获取元素以填充框架?
【发布时间】:2021-10-27 20:13:45
【问题描述】:

我是使用 Tkinter 进行 Python GUI 开发的新手。 我正在尝试使应用程序窗口具有一定大小,并且我希望窗口中的网络摄像头视图填充主窗口的大小。

当我设置窗口大小时,网络摄像头不会填满整个窗口。

自定义窗口大小时如何让元素填满整个窗口?

这是我的代码:

import tkinter as tk
from PIL import Image, ImageTk
import cv2

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)
        self.canvas.pack(fill="both", expand=True)

        # 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()
    root.geometry('600x800')
    # root.resizable(width=0, height=0)
    MainWindow(root, cv2.VideoCapture(0))

    root.mainloop()

谢谢。

【问题讨论】:

    标签: python opencv tkinter cv2


    【解决方案1】:

    您所要做的就是调整图像大小以适合画布大小。您可以使用cv2.resize()Image.resize() 调整图像大小。

    要获取当前画布大小,请使用canvas.winfo_height()canvas.wifo_width()。除此之外,您还应该考虑使用canvas.itemconfig(tag_id) 更新现有图像,而不是每次都创建一个新图像。

    示例代码(我将使用标签而不是画布来显示图像):

    import tkinter as tk
    from PIL import Image, ImageTk
    import cv2
    
    class MainWindow():
        def __init__(self, window, cap):
            self.window = window
            self.cap = cap
    
            self.interval = 20 # Interval in ms to get the latest frame
            # Create canvas for image
            self.vid_lbl = tk.Label(self.window)
            self.vid_lbl.pack(fill="both", expand=True)
    
            # Update image on canvas
            self.update_image()
    
        def update_image(self):
            # Get the latest frame and convert image format
    
            width, height = self.vid_lbl.winfo_width(), self.vid_lbl.winfo_height()
    
            self.image = cv2.cvtColor(self.cap.read()[1], cv2.COLOR_BGR2RGB) # to RGB
            self.image = cv2.resize(self.image, (width, height), cv2.INTER_AREA)
            self.image = Image.fromarray(self.image) # to PIL format
            #self.image = self.image.resize((width, height))
    
            self.image = ImageTk.PhotoImage(self.image) # to ImageTk format
            self.vid_lbl.config(image=self.image)
    
            # Repeat every 'interval' ms
            self.window.after(self.interval, self.update_image)
    
    if __name__ == "__main__":
        root = tk.Tk()
        root.geometry('600x800')
        # root.resizable(width=0, height=0)
        MainWindow(root, cv2.VideoCapture(0))
    
        root.mainloop()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-03
      • 2016-10-18
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 2017-03-09
      • 1970-01-01
      相关资源
      最近更新 更多