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

PyQt5点击按钮后window4窗口打开延迟问题求助

问题:PyQt5窗口打开延迟,被耗时操作阻塞

在PyQt5应用中,点击sendVideoBtn触发send_video函数时,调用open_info_window打开的window4会严重延迟,需等待--Process---输出后才显示。相关代码如下:

def open_customer_phone_number_window(self,filename):
    self.window3 = QMainWindow()
    self.phoneUi = Ui_PhoneMainWindow()
    self.phoneUi.setupUi(self.window3)
    self.window3.show()
    print(filename)
    self.phoneUi.sendVideoBtn.clicked.connect(partial(self.send_video,filename))

def open_info_window(self):
    self.window3.close()

    self.window4 = QMainWindow()
    self.sendInfoUi = Ui_SendInfoMainWindow()
    self.sendInfoUi.setupUi(self.window4)
    self.window4.show() # it showing very late

def send_video(self,filename):
    USER_PHONE = self.phoneUi.phoneNumber.text()
    FILE_NAME = filename
    self.open_info_window()
    print("--Process---")
    for i in range(101):
      time.sleep(0.05)
    # setting value to progress bar
      self.sendInfoUi.progressBar.setValue(i)
解决方案

问题根源

send_video中的time.sleep(0.05)和循环属于耗时操作,且运行在主线程中。PyQt的UI渲染(窗口显示、进度条更新)依赖主线程处理事件循环,耗时操作会阻塞主线程,导致window4的渲染被延后,必须等耗时操作完成后才会处理UI事件。

解决步骤

使用PyQt的QThread将耗时逻辑移到子线程,主线程仅负责UI初始化和信号传递:

  1. 定义进度更新子线程类
from PyQt5.QtCore import QThread, pyqtSignal
import time

class ProgressThread(QThread):
    progress_update = pyqtSignal(int)  # 用于传递进度值的信号

    def run(self):
        # 将原耗时循环移至子线程执行
        for i in range(101):
            time.sleep(0.05)
            self.progress_update.emit(i)  # 发送进度信号到主线程
  1. 修改原有函数逻辑
def open_info_window(self):
    self.window3.close()

    self.window4 = QMainWindow()
    self.sendInfoUi = Ui_SendInfoMainWindow()
    self.sendInfoUi.setupUi(self.window4)
    self.window4.show()

def send_video(self, filename):
    USER_PHONE = self.phoneUi.phoneNumber.text()
    FILE_NAME = filename
    self.open_info_window()
    
    # 初始化并启动子线程
    self.progress_thread = ProgressThread()
    # 连接子线程的进度信号到进度条的setValue方法
    self.progress_thread.progress_update.connect(self.sendInfoUi.progressBar.setValue)
    self.progress_thread.start()
    
    print("--Process---")

说明

  • 子线程独立执行耗时操作,不会阻塞主线程的UI渲染,window4能立刻显示。
  • 通过pyqtSignal实现子线程到主线程的安全通信(PyQt禁止子线程直接操作UI组件),进度条会实时更新。
  • 原代码中即使在循环内更新进度条,也会因主线程阻塞无法实时显示,改用子线程后可解决该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:00:45