QMainWindow关闭时QWidget内部控件不显示问题求助
解决QMainWindow关闭时Loader窗口控件不显示的问题
问题根源
你的代码中,uploadFile是同步阻塞操作,在close_event里调用它时,主线程会被完全占用,无法处理Loader窗口的UI绘制事件,导致窗口弹出但内部控件无法渲染。
解决方案
把FTP上传操作放到子线程中执行,让主线程能继续处理UI更新。具体实现如下:
修改后的主窗口与Loader控件代码
import sys from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel from PySide6.QtGui import QFont from PySide6.QtCore import Qt, QThread, Signal import upload # 导入你的上传模块 class UploadThread(QThread): # 定义信号,用于上传完成或出错时通知主线程 upload_finished = Signal() upload_failed = Signal(str) def __init__(self, filename, index): super().__init__() self.filename = filename self.index = index def run(self): try: upload.uploadFile(self.filename, self.index) self.upload_finished.emit() except Exception as e: self.upload_failed.emit(str(e)) class Loader(QWidget): def __init__(self): super().__init__() self.setWindowTitle('ManagerBee - Loader') self.resize(250, 130) self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint | Qt.WindowTitleHint) self.setAttribute(Qt.WA_DeleteOnClose) h1 = QFont() h1.setPointSize(9) h1.setBold(True) layout = QVBoxLayout(self) self.loaderText = QLabel("Auto Backup is in progress.<br/>System will close automatically.") self.loaderText.setFont(h1) self.loaderText.setAlignment(Qt.AlignCenter) layout.addWidget(self.loaderText) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("My Main Window") # 示例初始化userData,实际根据你的业务逻辑赋值 self.userData = ["123"] def closeEvent(self, event): # 先阻止窗口关闭,等待上传完成 event.ignore() # 创建并显示Loader窗口 self.closingLoader = Loader() self.closingLoader.show() # 创建上传线程并启动 self.upload_thread = UploadThread('db.sqlite3', str(self.userData[0])) self.upload_thread.upload_finished.connect(self.on_upload_finished) self.upload_thread.upload_failed.connect(self.on_upload_failed) self.upload_thread.start() def on_upload_finished(self): # 上传完成,关闭Loader并真正关闭主窗口 self.closingLoader.close() self.close() def on_upload_failed(self, error_msg): # 上传失败,关闭Loader并处理错误 self.closingLoader.close() # 这里可替换为你的错误提示框逻辑 print(f"上传失败: {error_msg}") self.close() if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()
修改后的FTP上传代码
import ftplib import os import shutil import datetime from alertbox import AlertBox import db FTP_HOST = "ftp.domain.com" FTP_USER = "user@domain.com" FTP_PASS = "iCQL^7;eIpbD" def uploadFile(filename, index): try: ftp = ftplib.FTP(FTP_HOST, FTP_USER, FTP_PASS) except Exception as e: # 抛出异常让线程捕获 raise Exception("无法连接网络:无互联网连接,自动备份失败") from e ftp.encoding = "utf-8" local_file = f"{index}_{filename}" shutil.copy(filename, local_file) with open(local_file, "rb") as file: ftp.storbinary(f"STOR {local_file}", file) os.remove(local_file) ftp.quit() # downloadFile代码保持不变,此处省略
关键修改点
- 新增
UploadThread类,将上传逻辑移到子线程执行,避免阻塞主线程UI更新 - 在
closeEvent中先忽略窗口关闭事件,启动线程后再显示Loader - 通过线程信号通知主线程上传状态,完成后再关闭Loader和主窗口
- 修改
uploadFile使其抛出异常,方便线程捕获并处理错误场景
内容的提问来源于stack exchange,提问作者Sayan
相关产品推荐
相关产品推荐

