tk运行了CV的摄像头为什么调用filedialog.askopenfilename()怎么样能同时进行
时间: 2024-04-21 20:30:22 浏览: 53
在调用 `filedialog.askopenfilename()` 时,会弹出文件选择对话框,这个对话框会阻塞程序的运行,到用户选择了文件或关闭了对话框。而在调用摄像头时,摄像头会占用系统资源,如果在摄像头运行时再打开文件选择对话框,就会出现卡顿或者崩溃的情况。
要解决这个问题,可以使用多线程的方式,将摄像头运行和文件选择对话框放在不同的线程中运行。这样就能同时进行摄像头运行和文件选择对话框的操作,而不会相互影响。例如,在主线程中运行摄像头,另开一个线程来运行文件选择对话框,并在选择完文件后将文件路径传递回主线程进行后续处理。
相关问题
import cv2 import tkinter as tk from tkinter import * from PIL import Image, ImageTk#图像控件 from Background.Thread_Demo import Thread_data class Two_Layout(): def __init__(self, top): self.top = top self.one = True self.canvas2 = Canvas(self.top, bg='LightSkyBlue', width=1100, height=610, highlightthickness=2, highlightbackground='Black') self.canvas2.place(x=0, y=28) self.delay = 15 # 更新画面的时间间隔(ms) Thread_data(self.windows_display()) def video(self): return cv2.VideoCapture(0) def windows_display(self): if self.one is True: self.cap = self.video() self.one = False ref, frame = self.cap.read() self.canvas2.delete('all') label = tk.Label(self.canvas2, text='未接入摄像头!', font=("黑体", 25), width=15, height=1) if ref is False: label.place(x=400, y=300, anchor='nw') self.cap = cv2.VideoCapture(0) else: for widget in self.canvas2.winfo_children(): widget.destroy() image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image1 = Image.fromarray(image) image2 = image1.resize((1100, 645), Image.ANTIALIAS) self.photo = ImageTk.PhotoImage(image=image2) self.canvas2.create_image(0, 0, image=self.photo, anchor=tk.NW) self.canvas2.after(self.delay, self.windows_display)他这里后面调用了filedialog.askopenfilename()会冲突为什么已经用了线程了呀
即使使用了线程,GUI 应用程序仍然是单线程的,即所有 GUI 操作都必须在主线程中完成。如果您在另一个线程中调用了 filedialog.askopenfilename(),它会尝试创建一个新的窗口,但由于不在主线程中,因此会出现冲突。因此,您需要使用 tkinter 的 after() 方法在主线程中调用 filedialog.askopenfilename() 方法来避免冲突。
import threading import cv2 import tkinter as tk from tkinter import * from PIL import Image, ImageTk#图像控件 from Background.Thread_Demo import Thread_data from Data_demo import data_demo class Two_Layout(): def init(self, top): self.top = top self.canvas2 = Canvas(self.top, bg='LightSkyBlue', width=1100, height=610, highlightthickness=2, highlightbackground='Black') self.canvas2.place(x=0, y=28) data_demo.display_id = self.canvas2 Thread_data(self.Thread_()) def Thread_(self): self.cap = cv2.VideoCapture(0) t = threading.Thread(target=self.windows_display()) t.start() def windows_display(self): ref, frame = self.cap.read() data_demo.display_id.delete('all') label = tk.Label(data_demo.display_id, text='未接入摄像头!', font=("黑体", 25), width=15, height=1) if ref is False: label.place(x=400, y=300, anchor='nw') self.cap = cv2.VideoCapture(0) else: for widget in data_demo.display_id.winfo_children(): widget.destroy() image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image1 = Image.fromarray(image) image2 = image1.resize((1100, 645), Image.ANTIALIAS) self.photo = ImageTk.PhotoImage(image=image2) data_demo.display_id.create_image(0, 0, image=self.photo, anchor=tk.NW) data_demo.display_id.after(15, self.windows_display)为什么在其他地方调用的filedialog.askopenfilename()起了冲突
这可能是由于你在其他部分的代码中使用了 `Tk()`,而这会创建一个新的主窗口,可能会影响你之前创建的主窗口和其他部件。你可以尝试使用 `Toplevel()` 创建一个子窗口,然后在子窗口中使用 `filedialog.askopenfilename()`,而不是在主窗口中使用。另外,确认你的代码中是否正确导入了 `filedialog`。如果你仍然无法解决问题,请提供更多的细节和代码,以便我能够更好地帮助你。
阅读全文