You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PyQt Widget中嵌入视频及网络摄像头流?

嘿,这两个问题我刚好有实操经验,给你详细捋一捋:

在PyQt Widget中嵌入视频的两种常用方法

方法1:使用Qt自带的QMediaPlayer + QVideoWidget

这个方法适合播放本地视频或者支持流媒体协议(比如RTSP)的网络视频,不需要额外依赖PyQt之外的库。核心步骤如下:

  • 导入PyQt5.QtMultimedia和PyQt5.QtMultimediaWidgets模块
  • 创建QMediaPlayer实例,设置媒体源(本地文件路径或网络流URL)
  • 创建QVideoWidget作为视频显示载体,将其设为播放器的输出目标
  • 把QVideoWidget添加到布局或Widget中,调用播放器的play()方法启动播放

简单代码片段示例:

from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtCore import QUrl

class VideoEmbedWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setLayout(QVBoxLayout())
        
        # 初始化视频显示控件
        self.video_display = QVideoWidget()
        self.layout().addWidget(self.video_display)
        
        # 初始化媒体播放器
        self.player = QMediaPlayer()
        self.player.setVideoOutput(self.video_display)
        
        # 设置媒体源(可替换为本地视频路径或网络流URL)
        # media_source = QMediaContent(QUrl.fromLocalFile("local_video.mp4"))
        media_source = QMediaContent(QUrl("rtsp://your_stream_address"))
        self.player.setMedia(media_source)
        
        # 添加播放控制按钮
        play_btn = QPushButton("开始播放")
        play_btn.clicked.connect(self.player.play)
        self.layout().addWidget(play_btn)

⚠️ 注意:如果播放网络流或特殊格式视频,可能需要系统安装对应多媒体解码器,否则可能无法正常播放。

方法2:使用OpenCV + QLabel

这个方法兼容性更强,尤其适合处理摄像头流(本地摄像头/网络摄像头流),因为OpenCV对各类视频源的支持更灵活。核心逻辑是:用OpenCV读取视频帧 → 转换成Qt可识别的QImage → 显示在QLabel上 → 用QTimer定时刷新帧。

首先需要安装依赖包:pip install opencv-python

代码示例:

from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton
from PyQt5.QtCore import QTimer, Qt
from PyQt5.QtGui import QImage, QPixmap
import cv2

class CameraStreamWidget(QWidget):
    def __init__(self, stream_url=None):
        super().__init__()
        self.setLayout(QVBoxLayout())
        
        # 初始化显示标签
        self.stream_label = QLabel()
        self.stream_label.setAlignment(Qt.AlignCenter)
        self.layout().addWidget(self.stream_label)
        
        # 初始化视频捕获对象:stream_url为None则调用本地摄像头,否则用网络流链接
        self.cap = cv2.VideoCapture(stream_url if stream_url else 0)
        
        # 定时刷新帧(约30fps)
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_stream_frame)
        self.timer.start(30)
        
        # 添加停止按钮
        stop_btn = QPushButton("停止流")
        stop_btn.clicked.connect(self.stop_stream)
        self.layout().addWidget(stop_btn)
    
    def update_stream_frame(self):
        ret, frame = self.cap.read()
        if ret:
            # 将OpenCV的BGR格式转为Qt的RGB格式
            rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            h, w, ch = rgb_frame.shape
            bytes_per_line = ch * w
            q_image = QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888)
            # 按比例缩放显示
            self.stream_label.setPixmap(QPixmap.fromImage(q_image).scaled(
                self.stream_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation
            ))
    
    def stop_stream(self):
        self.timer.stop()
        self.cap.release()
        self.stream_label.clear()
    
    def closeEvent(self, event):
        # 窗口关闭时自动释放资源
        self.stop_stream()
        super().closeEvent(event)
关于Qt Designer内置功能与弹出摄像头小窗口的实现

首先明确:Qt Designer本身没有内置直接拖拽就能嵌入摄像头流的控件,但我们可以通过「自定义控件+代码结合」的方式实现你想要的效果——点击按钮弹出仅显示摄像头流的独立小窗口。

具体实现步骤:

  1. 在Qt Designer中设计主窗口,添加一个按钮(比如命名为pushButton_open_cam),然后用pyuic5工具将.ui文件转换为Python代码。
  2. 编写主窗口逻辑代码,绑定按钮点击事件,在事件中实例化上面的CameraStreamWidget(或用QDialog作为窗口容器)并显示。

示例代码(假设.ui转成的文件名为main_ui.py):

from PyQt5.QtWidgets import QMainWindow, QApplication
from main_ui import Ui_MainWindow
import sys

class MainApp(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        # 绑定按钮点击事件
        self.pushButton_open_cam.clicked.connect(self.launch_camera_window)
    
    def launch_camera_window(self):
        # 替换为你的网络摄像头流链接
        self.cam_window = CameraStreamWidget(stream_url="your_webcam_stream_url")
        self.cam_window.setWindowTitle("摄像头流")
        self.cam_window.resize(640, 480)  # 设置窗口初始大小
        self.cam_window.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainApp()
    window.show()
    sys.exit(app.exec_())

这样点击按钮后,就会弹出一个独立的小窗口专门显示摄像头流,无需再调用Edge浏览器。

如果你想在Qt Designer中直接预览自定义控件,可以开发Qt Designer插件,但日常开发中直接结合.ui文件和代码就足够高效了。

内容的提问来源于stack exchange,提问作者skular

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 17:22:29