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

PyQt5动态添加摄像头标签:奇数数量布局适配问题求助

PyQt5 动态适配奇数数量摄像头的布局实现

布局逻辑

针对奇数数量的摄像头,采用「首行单个占满整行,剩余偶数个按每行2个均分」的布局方案,既保证界面美观,又兼容原有偶数数量的布局逻辑:

  • 当摄像头数量为奇数时,先添加一个占满整行的视频控件;
  • 剩余的偶数个控件按原有逻辑,每2个一组放在同一行,依次添加到主布局中。

修改后的完整代码

from PyQt5.QtWidgets import (QApplication, QWidget, QFrame, QLabel, 
                             QVBoxLayout, QHBoxLayout, QSpinBox, QPushButton)
from PyQt5.QtCore import Qt
import sys

class CamWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("摄像头动态布局")
        self.resize(800, 600)

        # 顶部控制区:选择摄像头数量
        control_layout = QHBoxLayout()
        self.spin_box = QSpinBox()
        self.spin_box.setRange(1, 8)
        self.spin_box.setValue(3)
        self.confirm_btn = QPushButton("设置摄像头数量")
        self.confirm_btn.clicked.connect(self.loopCamFeed)
        control_layout.addWidget(self.spin_box)
        control_layout.addWidget(self.confirm_btn)

        # 视频显示区域
        self.video_widget = QWidget()
        self.main_layout = QVBoxLayout(self.video_widget)

        # 主布局
        overall_layout = QVBoxLayout(self)
        overall_layout.addLayout(control_layout)
        overall_layout.addWidget(self.video_widget)

        # 初始加载布局
        self.loopCamFeed()

    def loopCamFeed(self):
        count = self.spin_box.value()

        # 清空原有布局,避免重复添加控件
        while self.main_layout.count():
            child = self.main_layout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()
            elif child.layout():
                # 清空嵌套的布局
                while child.layout().count():
                    sub_child = child.layout().takeAt(0)
                    if sub_child.widget():
                        sub_child.widget().deleteLater()

        # 处理奇数数量的情况
        if count % 2 == 1:
            # 添加首行单个控件(占满整行)
            h_layout = QHBoxLayout()
            self.create_cam_frame(h_layout, 1)
            self.main_layout.addLayout(h_layout)
            remaining_count = count - 1
            start_idx = 2
        else:
            remaining_count = count
            start_idx = 1

        # 处理剩余偶数个控件,每行2个
        for i in range(0, remaining_count, 2):
            h_layout = QHBoxLayout()
            self.create_cam_frame(h_layout, start_idx + i)
            if start_idx + i + 1 <= count:
                self.create_cam_frame(h_layout, start_idx + i + 1)
            self.main_layout.addLayout(h_layout)

    def create_cam_frame(self, parent_layout, cam_id):
        # 创建承载视频的QFrame和QLabel
        frame = QFrame()
        frame.setStyleSheet("border: 2px solid #4CAF50; border-radius: 4px;")
        frame.setMinimumSize(200, 150)
        
        label = QLabel()
        label.setAlignment(Qt.AlignCenter)
        label.setText(f"摄像头 {cam_id}")
        label.setStyleSheet("color: #333; font-size: 16px;")

        frame_layout = QVBoxLayout(frame)
        frame_layout.addWidget(label)
        parent_layout.addWidget(frame)

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

布局效果展示

3个摄像头布局

3个摄像头布局
(效果说明:首行显示1个占满整行的视频控件,底部一行显示2个等宽的视频控件,整体布局均匀美观)

5个摄像头布局

5个摄像头布局
(效果说明:首行1个控件,后续两行各显示2个控件,保持界面整洁)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:50:31