Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyQt小部件的大小不断增加,并退出窗口_Python_Python 3.x_User Interface_Pyqt_Pyqt5 - Fatal编程技术网

Python PyQt小部件的大小不断增加,并退出窗口

Python PyQt小部件的大小不断增加,并退出窗口,python,python-3.x,user-interface,pyqt,pyqt5,Python,Python 3.x,User Interface,Pyqt,Pyqt5,我已经用PyQt5编写了一个应用程序。我基本上是在显示一个摄像头提要(在本例中是我的网络摄像头),但问题是,在运行时帧大小不断增加,最终会从我的笔记本电脑屏幕上消失。我想不出是什么问题 谁能解释一下我做错了什么 下面是代码片段 from PyQt5 import QtCore, QtGui, QtWidgets from threading import Thread from collections import deque from datetime import datetime impo

我已经用PyQt5编写了一个应用程序。我基本上是在显示一个摄像头提要(在本例中是我的网络摄像头),但问题是,在运行时帧大小不断增加,最终会从我的笔记本电脑屏幕上消失。我想不出是什么问题

谁能解释一下我做错了什么

下面是代码片段

from PyQt5 import QtCore, QtGui, QtWidgets
from threading import Thread
from collections import deque
from datetime import datetime
import time
import sys
import cv2
import imutils


class CameraWidget(QtWidgets.QWidget):
    """Independent camera feed
    Uses threading to grab IP camera frames in the background

    @param width - Width of the video frame
    @param height - Height of the video frame
    @param stream_link - IP/RTSP/Webcam link
    @param aspect_ratio - Whether to maintain frame aspect ratio or force into fraame
    """

    def __init__(self, width=0, height=0, aspect_ratio=False, parent=None, deque_size=1):
        super(CameraWidget, self).__init__(parent)

        # Initialize deque used to store frames read from the stream
        self.deque = deque(maxlen=deque_size)
        
        self.maintain_aspect_ratio = aspect_ratio
        self.camera_stream_link = 0

        # Flag to check if camera is valid/working
        self.online = False
        self.capture = None

        self.video_frame = QtWidgets.QLabel()

        self.load_network_stream()

        # Start background frame grabbing
        self.get_frame_thread = Thread(target=self.get_frame, args=())
        self.get_frame_thread.daemon = True
        self.get_frame_thread.start()

        # Periodically set video frame to display
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.set_frame)
        self.timer.start(.5)

        print('Started camera: {}'.format(self.camera_stream_link))

    def load_network_stream(self):
        """Verifies stream link and open new stream if valid"""

        def load_network_stream_thread():
            if self.verify_network_stream(self.camera_stream_link):
                self.capture = cv2.VideoCapture(self.camera_stream_link)
                self.online = True
        self.load_stream_thread = Thread(target=load_network_stream_thread, args=())
        self.load_stream_thread.daemon = True
        self.load_stream_thread.start()

    def verify_network_stream(self, link):
        """Attempts to receive a frame from given link"""

        cap = cv2.VideoCapture(link)
        if not cap.isOpened():
            return False
        cap.release()
        return True

    def get_frame(self):
        # time.sleep(5)
        """Reads frame, resizes, and converts image to pixmap"""

        while True:
            try:
                if self.capture.isOpened() and self.online:
                    # Read next frame from stream and insert into deque
                    status, frame = self.capture.read()
                    if status:
                        self.deque.append(frame)
                    else:
                        self.capture.release()
                        self.online = False
                else:
                    # Attempt to reconnect
                    print('attempting to reconnect', self.camera_stream_link)
                    self.load_network_stream()
                    self.spin(2)
                self.spin(.001)
            
            except AttributeError:
                pass

    def spin(self, seconds):
        """Pause for set amount of seconds, replaces time.sleep so program doesnt stall"""

        time_end = time.time() + seconds
        while time.time() < time_end:
            QtWidgets.QApplication.processEvents()

    def set_frame(self):
        """Sets pixmap image to video frame"""

        if not self.online:
            self.spin(1)
            return

        if self.deque and self.online:
            # Grab latest frame
            frame = self.deque[-1]

            # Keep frame aspect ratio
            if self.maintain_aspect_ratio:
                self.frame = imutils.resize(frame, width=self.screen_width)
            # Force resize
            else:
                self.frame = cv2.resize(frame, (self.screen_width, self.screen_height))
                self.frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
                h, w, ch = self.frame.shape
                bytesPerLine = ch * w

            # Convert to pixmap and set to video frame
            self.img = QtGui.QImage(self.frame, w, h, bytesPerLine, QtGui.QImage.Format_RGB888)
            self.pix = QtGui.QPixmap.fromImage(self.img)
            self.video_frame.setPixmap(self.pix)

    def set_frame_params(self, width, height):
        self.screen_width = width
        self.screen_height = height

    def get_video_frame(self):
        self.video_frame.setScaledContents(True)
        return self.video_frame


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        # Middle frame
        self.mid_frame = QtWidgets.QFrame()
        self.mid_frame.setStyleSheet("background-color: rgb(153, 187, 255)")

        self.camera = CameraWidget()

        # Create camera widgets
        print('Creating Camera Widgets...')
        self.video_frame = self.camera.get_video_frame()

        self.mid_layout = QtWidgets.QHBoxLayout()
        self.mid_layout.addWidget(self.video_frame)
        self.mid_frame.setLayout(self.mid_layout)


        self.widget = QtWidgets.QWidget()
        self.layout = QtWidgets.QVBoxLayout()
        self.layout.addWidget(self.mid_frame)
        self.layout.setContentsMargins(0,0,0,0)
        self.layout.setSpacing(0)
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)

    def event(self, e):
        if e.type() in (QtCore.QEvent.Show, QtCore.QEvent.Resize):
            print("resize ", self.mid_frame.width(), self.mid_frame.height())
            self.camera.set_frame_params(self.mid_frame.width()-10, self.mid_frame.height()-10)
        return QtWidgets.QMainWindow.event(self, e)


if __name__ == '__main__':

    # Create main application window
    app = QtWidgets.QApplication([])
    app.setStyle(QtWidgets.QStyleFactory.create("Cleanlooks"))
    w = MainWindow()
    w.showMaximized()
    sys.exit(app.exec_())
从PyQt5导入QtCore、QtGui、qtwidget
从线程导入线程
从集合导入deque
从日期时间导入日期时间
导入时间
导入系统
进口cv2
导入imutils
类CameraWidget(QtWidgets.QWidget):
独立摄像机馈送
使用线程在背景中捕获IP摄像头帧
@param width—视频帧的宽度
@param height—视频帧的高度
@参数流链接-IP/RTSP/Webcam链接
@参数纵横比-是保持帧纵横比还是强制进入帧
"""
定义初始值(自,宽度=0,高度=0,纵横比=False,父项=None,定义大小=1):
超级(CameraWidget,self)。\u初始化\u(父级)
#初始化用于存储从流读取的帧的deque
self.deque=deque(maxlen=deque\u尺寸)
self.maintage\u aspect\u ratio=aspect\u ratio
self.camera\u stream\u link=0
#用于检查摄像机是否有效/工作的标志
self.online=False
self.capture=无
self.video_frame=qtwidts.QLabel()
self.load\u网络\u流()
#开始背景帧抓取
self.get\u frame\u thread=thread(target=self.get\u frame,args=())
self.get\u frame\u thread.daemon=True
self.get\u frame\u thread.start()
#定期设置要显示的视频帧
self.timer=QtCore.QTimer()
self.timer.timeout.connect(self.set\u帧)
self.timer.start(.5)
打印('Started camera:{}'。格式(self.camera\u stream\u link))
def加载网络流(自):
“”“验证流链接并打开新流(如果有效)”
def load_network_stream_thread():
如果自验证网络流(自摄像机流链接):
self.capture=cv2.VideoCapture(self.camera\u stream\u链接)
self.online=True
self.load\u stream\u thread=thread(target=load\u network\u stream\u thread,args=())
self.load\u stream\u thread.daemon=True
self.load\u stream\u thread.start()
def验证网络流(自身、链路):
“”“尝试从给定链接接收帧”“”
cap=cv2.视频捕获(链接)
如果不是cap.ISOPEND():
返回错误
第1章释放()
返回真值
def get_帧(自身):
#时间。睡眠(5)
“”“读取帧、调整大小并将图像转换为像素贴图”“”
尽管如此:
尝试:
如果self.capture.isOpened()和self.online:
#从流中读取下一帧并插入到deque中
状态,frame=self.capture.read()
如果状态:
self.deque.append(框架)
其他:
self.capture.release()
self.online=False
其他:
#尝试重新连接
打印('尝试重新连接',self.camera\u stream\u link)
self.load\u网络\u流()
自转(2)
自转(.001)
除属性错误外:
通过
def旋转(自身,秒):
“”“暂停设置的秒数,替换时间。休眠,使程序不会暂停”“”
time_end=time.time()+秒
while time.time()