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
相关产品推荐
相关产品推荐

