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

PyQt5项目图片实时刷新失效及双窗口异常问题求助

问题1:透明无框窗口图片实时刷新失效,多线程导致无响应

问题原因

  • 嵌套QLabel逻辑错误:实际显示图片的是self.label.lbl,但刷新时给父容器self.label设置Pixmap,界面无变化。
  • 多线程违规操作UI:PyQt要求所有UI操作必须在主线程执行,子线程直接调用UI方法会触发窗口无响应或崩溃。
  • 刷新逻辑硬编码:固定使用./some_file2.png而非全局变量path_of_image;调整的是App窗口大小而非实际显示的self.w_主窗口。
  • 冗余事件处理:定时器回调中调用QApplication.processEvents()无意义,QTimer本身运行在主线程事件循环内。

修复后代码

from PyQt5 import QtCore, QtGui, QtWidgets
import sys

path_of_image = './some_file.png'

class App(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
        QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)

        self.w_ = QtWidgets.QMainWindow()
        self.w_.setWindowFlags(
            QtCore.Qt.SplashScreen | 
            QtCore.Qt.FramelessWindowHint | 
            QtCore.Qt.WindowStaysOnTopHint
        )
        self.w_.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.w_.setStyleSheet("background:transparent;")

        # 仅保留一个用于显示图片的QLabel
        self.image_label = QtWidgets.QLabel(self.w_)
        self.image_label.setGeometry(QtCore.QRect(615, 292, 200, 200))
        self.image_label.setPixmap(QtGui.QPixmap(path_of_image))
        self.image_label.resize(200, 200)

        self.w_.showFullScreen()

        # 定时器设置,1秒刷新一次
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.update_image)
        self.timer.start(1000)

    def update_image(self):
        pixmap = QtGui.QPixmap(path_of_image)
        if not pixmap.isNull():
            self.image_label.setPixmap(pixmap)
            # 如需根据图片尺寸调整标签大小,取消下方注释
            # self.image_label.adjustSize()
            print("图片刷新成功")
        else:
            print("图片加载失败")

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

问题2:二维码刷新功能出现两个窗口

问题原因

  • 重复创建窗口实例:主函数中创建QLabel并调用show(),同时onFinished回调每次新建QMainWindow并全屏显示,导致两个窗口共存。
  • 窗口重复初始化:每次网络请求完成都创建新主窗口,未复用已存在的窗口实例。

修复后代码

from PyQt5 import QtCore, QtWidgets, QtNetwork
import sys

class Loader(QtCore.QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._manager = QtNetwork.QNetworkAccessManager()
        self._manager.finished.connect(self.onFinished)
        # 初始化一次窗口,避免重复创建
        self._init_window()

    def _init_window(self):
        self.w_ = QtWidgets.QMainWindow()
        self.w_.setWindowFlags(
            QtCore.Qt.SplashScreen | 
            QtCore.Qt.FramelessWindowHint | 
            QtCore.Qt.WindowStaysOnTopHint
        )
        self.w_.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.w_.setStyleSheet("background:transparent;")

        self.image_label = QtWidgets.QLabel(self.w_)
        self.image_label.setGeometry(QtCore.QRect(615, 292, 200, 200))
        self.image_label.resize(200, 200)
        self.w_.showFullScreen()

    def start(self, url):
        self._url = url
        self.request()

    def request(self):
        req = QtNetwork.QNetworkRequest(QtCore.QUrl(self._url))
        self._manager.get(req)

    def onFinished(self, reply):
        data = reply.readAll()
        pixmap = QtGui.QPixmap()
        if pixmap.loadFromData(data):
            self.image_label.setPixmap(pixmap)
            print("二维码刷新成功")
        else:
            print("二维码加载失败")
        # 1秒后再次请求刷新
        QtCore.QTimer.singleShot(1000, self.request)

if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    loader = Loader()
    url = "http://172.17.135.67:5421/api/download?filename=/some_file2.png"
    loader.start(url)
    app.exec()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 02:30:41