如何让 Tkinter windows 中的元素填充框架?
How can I get elements in Tkinter windows to fill the frame?
我是 Python 使用 Tkinter 进行 GUI 开发的新手。
我正在尝试使应用程序 window 具有一定的大小,并且我希望 window 中的网络摄像头视图能够填充主 window.
的大小
当我设置 window 大小时,网络摄像头没有填满整个 window。
自定义window大小时如何让元素填满整个window?
这是我的代码:
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()
谢谢。
您所要做的就是调整图像大小以适合 canvas 尺寸。您可以使用 cv2.resize()
或 Image.resize()
来调整图像大小。
要获得当前 canvas 大小,请使用 canvas.winfo_height()
和 canvas.wifo_width()
。除此之外,您还应该考虑使用 canvas.itemconfig(tag_id)
更新现有图像,而不是每次都创建一个新图像。
示例代码(我将使用标签而不是 canvas 来显示图像):
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()
我是 Python 使用 Tkinter 进行 GUI 开发的新手。 我正在尝试使应用程序 window 具有一定的大小,并且我希望 window 中的网络摄像头视图能够填充主 window.
的大小当我设置 window 大小时,网络摄像头没有填满整个 window。
自定义window大小时如何让元素填满整个window?
这是我的代码:
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()
谢谢。
您所要做的就是调整图像大小以适合 canvas 尺寸。您可以使用 cv2.resize()
或 Image.resize()
来调整图像大小。
要获得当前 canvas 大小,请使用 canvas.winfo_height()
和 canvas.wifo_width()
。除此之外,您还应该考虑使用 canvas.itemconfig(tag_id)
更新现有图像,而不是每次都创建一个新图像。
示例代码(我将使用标签而不是 canvas 来显示图像):
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()