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

PyQt5中亮模式Label无法置顶但暗模式正常问题排查

PyQt5摄像头画面显示问题:亮模式下clearlabel无法正常置顶覆盖画面

我正在开发基于PyQt5的程序,通过QPixmap显示摄像头画面。点击“开始”按钮后,摄像头画面会被捕获并持续更新到image_label;点击“停止”按钮时,我通过将clearlabel置顶(raise_())、置底(lower())的方式清除画面,避免残留最后一帧。

使用qdarkstyle库,当系统检测到暗模式时自动为程序应用样式表。暗模式下启动程序,视频显示正常,点击停止后clearlabel可正常置顶覆盖画面;但亮模式下执行相同代码,clearlabel却无法正常置顶。

最小复现代码

from PyQt5 import QtGui, QtWidgets
from PyQt5.uic import loadUi
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QThread
from PyQt5.QtGui import QPixmap
import numpy as np
import sys
import darkdetect
import qdarkstyle
import cv2
import time

class VideoThread(QThread):
    change_pixmap_signal = pyqtSignal(np.ndarray)

    def __init__(self):
        super().__init__()
        self._run_flag = True

    def run(self):
        wCam, hCam = 640, 480

        # capture from web cam
        cap = cv2.VideoCapture(0)
        assert cap.isOpened()
        cap.set(3, wCam)
        cap.set(4, hCam)

        while self._run_flag:
            # Get image frame
            success, img = cap.read()
            if not success:
                break

            if success:
                self.change_pixmap_signal.emit(img)
        # shut down capture system
        cap.release()

    def stop(self):
        self._run_flag = False
        self.wait()


class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        loadUi("mainwindow.ui", self)
        self.setWindowTitle("Hand Tracker")
        self.display_width = 640
        self.display_height = 480
        self.firsttime = 1
        if darkdetect.isDark() == True:
            self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())

        # start the thread
        self.gesture.clicked.connect(self.gotowindow2)
        self.startbutton.clicked.connect(self.startvideo)
        self.darkmodecheck.clicked.connect(self.darkmode)

    def darkmode(self):
        print(darkdetect.isDark())

    def gotowindow2(self):
        widget.setCurrentIndex(widget.currentIndex() + 1)  # changes index by 1 to change page

    def startvideo(self):
        # Change label color to light blue
        self.startbutton.clicked.disconnect(self.startvideo)

        self.clearlabel.lower()
        # Change button to stop
        self.startbutton.setText('Stop video')
        self.thread = VideoThread()
        self.thread.change_pixmap_signal.connect(self.update_image)
        # start the thread
        self.thread.start()
        if self.firsttime == 0:
            time.sleep(4)
            self.firsttime = 0

        self.startbutton.clicked.connect(self.thread.stop)  # Stop the video if button clicked
        self.startbutton.clicked.connect(self.stopvideo)
        self.firsttime = 0

    def stopvideo(self):
        self.thread.change_pixmap_signal.disconnect()
        self.clearlabel.raise_()
        self.startbutton.setText('Start video')
        self.startbutton.clicked.disconnect(self.stopvideo)
        self.startbutton.clicked.disconnect(self.thread.stop)
        self.startbutton.clicked.connect(self.startvideo)

    def closeEvent(self, event):
        self.thread.stop()
        event.accept()

    @pyqtSlot(np.ndarray)
    def update_image(self, img):
        """Updates the image_label with a new opencv image"""
        qt_img = self.convert_cv_qt(img)
        self.image_label.setPixmap(qt_img)

    def convert_cv_qt(self, img):
        """Convert from an opencv image to QPixmap"""
        rgb_image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        h, w, ch = rgb_image.shape
        bytes_per_line = ch * w
        convert_to_Qt_format = QtGui.QImage(rgb_image.data, w, h, bytes_per_line, QtGui.QImage.Format_RGB888)
        p = convert_to_Qt_format.scaled(self.display_width, self.display_height, Qt.KeepAspectRatio)
        return QPixmap.fromImage(p)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    widget = QtWidgets.QStackedWidget()
    a = MainWindow()
    widget.addWidget(a)
    widget.show()
    sys.exit(app.exec_())

对应的UI文件

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1001</width>
    <height>650</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QLabel" name="image_label">
   <property name="enabled">
    <bool>true</bool>
   </property>
   <property name="geometry">
    <rect>
     <x>180</x>
     <y>20</y>
     <width>640</width>
     <height>480</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">QLabel{
border: 1px solid grey;
border-radius: 10px
}</string>
   </property>
   <property name="text">
    <string>Img</string>
   </property>
   <property name="alignment">
    <set>Qt::AlignCenter</set>
   </property>
  </widget>
  <widget class="QPushButton" name="startbutton">
   <property name="geometry">
    <rect>
     <x>340</x>
     <y>520</y>
     <width>111</width>
     <height>31</height>
    </rect>
   </property>
   <property name="mouseTracking">
    <bool>false</bool>
   </property>
   <property name="styleSheet">
    <string notr="true">QPushButton{
border-radius: 10px;
border: 0.5px solid grey;
} </string>
   </property>
   <property name="text">
    <string>Start Video</string>
   </property>
  </widget>
  <widget class="QPushButton" name="darkmodecheck">
   <property name="geometry">
    <rect>
     <x>170</x>
     <y>520</y>
     <width>113</width>
     <height>32</height>
    </rect>
   </property>
   <property name="text">
    <string>PushButton</string>
   </property>
  </widget>
  <widget class="QPushButton" name="gesture">
   <property name="geometry">
    <rect>
     <x>550</x>
     <y>520</y>
     <width>113</width>
     <height>32</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">QPushButton{
border-radius: 10px;
border: 0.5px solid grey;
} </string>
   </property>
   <property name="text">
    <string>Gestures</string>
   </property>
  </widget>
  <widget class="QLabel" name="clearlabel">
   <property name="enabled">
    <bool>true</bool>
   </property>
   <property name="geometry">
    <rect>
     <x>180</x>
     <y>20</y>
     <width>640</width>
     <height>480</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">QLabel{
border: 1px solid grey;
border-radius: 10px
}</string>
   </property>
   <property name="text">
    <string>Img</string>
   </property>
   <property name="alignment">
    <set>Qt::AlignCenter</set>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:55:17