self.bool = True self.label.destroy() self.cap = cv2.VideoCapture(0) t = threading.Thread(target=self.windows_display()) t.start() print("1") button_id.config(text='关闭摄像头', command=lambda: self.Cease_stop(button_id))为什么print(”1“)没有执行
时间: 2024-03-29 16:38:28 浏览: 99
在这段代码中,`t = threading.Thread(target=self.windows_display())`这一行中的`self.windows_display()`是直接调用了`windows_display()`函数,并且没有使用`args`参数进行传参。这会导致`target`参数中传入的不是一个函数,而是`windows_display()`函数的返回值。因此,线程启动时会直接执行`windows_display()`函数,而不是将它作为一个线程运行。这就导致了`windows_display()`函数一直运行,而`print("1")`无法执行。
要解决这个问题,可以将`t = threading.Thread(target=self.windows_display)`修改为`t = threading.Thread(target=self.windows_display)`,即不直接调用函数,而是将函数名作为参数传入。同时,需要将`self.windows_display()`中的`while`循环改为`if`语句或者其他控制循环运行的方法,以保证线程能够正常启动和结束。
相关问题
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 Camera(): def __init__(self, top): self.top = top self.h = int(data_demo.window_height // 1.5) self.w = int(data_demo.window_width // 1.74) self.canvas2 = Canvas(self.top, bg='LightSkyBlue', width=self.w, height=self.h, highlightthickness=2, highlightbackground='Black') self.canvas2.place(relx=0.0, rely=0.032) self.label = tk.Label(self.canvas2, text='摄像头显示区!', font=("黑体", 25), width=15, height=1) self.label.place(relx=0.32, rely=0.50, anchor='nw') def Firing_run(self, button_id): self.bool = True self.label.destroy() self.cap = cv2.VideoCapture(0) t = threading.Thread(target=self.windows_display) t.start() button_id.config(text='关闭摄像头', command=lambda: self.Cease_stop(button_id)) def Cease_stop(self, button_id): self.bool = False button_id.config(text='打开摄像头', command=lambda: self.Firing_run(button_id)) def windows_display(self): while self.bool: ref, frame = self.cap.read() cv2.waitKey(1) if ref: image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image1 = Image.fromarray(image) image2 = image1.resize((self.w, self.h), Image.ANTIALIAS) self.photo = ImageTk.PhotoImage(image=image2) self.canvas2.create_image(0, 0, image=self.photo, anchor=tk.NW) # self.canvas2.update() self.canvas2.after(15)中t = threading.Thread(target=self.windows_display)调用摄像头会闪烁,但是t = threading.Thread(target=self.windows_display())却不会
原因是当您使用`t = threading.Thread(target=self.windows_display)`时,它会将`self.windows_display()`作为一个参数,而不是一个可调用的函数。因此,线程将立即运行`self.windows_display()`函数,并将其返回值(None)传递给`t`。这意味着您的线程实际上不会运行`self.windows_display()`函数,而是只运行了一次,并立即停止。
相反,当您使用`t = threading.Thread(target=self.windows_display)`时,它会将`self.windows_display`作为一个可调用的函数传递给`t`,因此线程将运行`self.windows_display`函数,并在后台持续运行。
因此,您应该修改线程创建代码如下:
```
t = threading.Thread(target=self.windows_display)
```
而不是:
```
t = threading.Thread(target=self.windows_display())
```
def Firing_run(self, button_id): self.bool = True self.cap = cv2.VideoCapture(0) t = threading.Thread(target=self.windows_display) t.start() button_id.config(text='关闭摄像头', command=lambda: self.Cease_stop(button_id)) def Cease_stop(self, button_id): self.bool = False self.label.destroy() self.canvas2.delete("all") self.label = tk.Label(self.canvas2, text='摄像头显示区!', font=("黑体", 25), width=15, height=1) self.label.place(relx=0.32, rely=0.50, anchor='nw') button_id.config(text='打开摄像头', command=lambda: self.Firing_run(button_id)) def windows_display(self): if self.bool: ref, frame = self.cap.read() if ref: self.label.destroy() self.canvas2.delete("all") image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image1 = Image.fromarray(image) image2 = image1.resize((self.w, self.h), Image.ANTIALIAS) self.photo = ImageTk.PhotoImage(image=image2) self.canvas2.create_image(0, 0, image=self.photo, anchor=tk.NW) else: self.cap = cv2.VideoCapture(0) self.label.destroy() self.label = tk.Label(self.canvas2, text='未找到摄像头!', font=("黑体", 25), width=15, height=1) self.label.place(relx=0.32, rely=0.50, anchor='nw') self.canvas2.update() self.canvas2.after(15, self.windows_display)怎么停止self.windows_display
可以通过调用Cease_stop方法来停止self.windows_display。在Cease_stop方法中,将self.bool设置为False,这会导致self.windows_display停止递归调用。同时,删除当前self.label并清空self.canvas2。最后,将button_id的文本和命令设置为打开摄像头,并将其命令设置为self.Firing_run(button_id)。
阅读全文