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

PyQt使用QThread信号传递时Windows用户配置文件大小计算结果异常问题

核心问题:信号参数类型溢出

你定义的size_ready = pyqtSignal(int)使用了PyQt默认的32位有符号整数类型,它的最大值仅为2^31 - 1 = 2147483647(约2GB)。Windows用户配置文件的大小几乎都会超过这个值,Python原生int支持任意长度不会溢出,所以控制台打印结果正确,但是信号发射时会强制转换为32位有符号整数,发生溢出截断,导致UI拿到的数值错误。

修复方案:把信号参数类型改为pyqtSignal(object)或者pyqtSignal('qint64'),支持64位整数:

# 修改TailleRep类中的信号定义即可
size_ready = pyqtSignal(object)
# 或者明确指定64位整数类型
size_ready = pyqtSignal('qint64')

其他需要修复的潜在问题

1. 遍历文件夹时未处理权限异常

用户目录下存在大量系统保护的目录/文件,直接调用f.stat()会抛出权限异常,导致计算直接中断,结果偏小。需要在getFolderSize方法中捕获异常:

def getFolderSize(self, folder_path):
    total_size = 0
    start_path = Path(os.path.join(folder_path, '.'))
    for f in start_path.glob('**/*'):
        try:
            if f.is_file():
                total_size += f.stat().st_size
        except (PermissionError, OSError):
            # 跳过无权访问的路径
            continue
    return total_size

2. 线程生命周期管理缺失

当前计算完成后子线程不会自动退出,多次点击按钮会生成大量残留线程,还可能出现前一次计算的结果覆盖后一次的问题。需要添加信号绑定,计算完成后自动退出线程、清理资源:

def GetSize(self):
    self.getSizeBtn.setEnabled(False)
    self.thread = QThread()
    self.worker = TailleRep(os.getenv('USERPROFILE'))
    self.worker.moveToThread(self.thread)
    self.thread.started.connect(self.worker.work)  
    self.worker.size_ready.connect(self.size_ready)
    # 新增:计算完成后自动清理线程和worker资源
    self.worker.size_ready.connect(self.thread.quit)
    self.worker.size_ready.connect(self.worker.deleteLater)
    self.thread.finished.connect(self.thread.deleteLater)
    self.thread.start()

3. 避免遍历Windows自引用Junction目录

Windows用户目录下存在很多自引用的Junction目录(比如Application Data),部分Python版本会将其识别为普通目录递归遍历,导致重复计算甚至死循环,可以添加判断跳过Junction:

def is_junction(path: Path) -> bool:
    try:
        return bool(os.readlink(path))
    except OSError:
        return False

def getFolderSize(self, folder_path):
    total_size = 0
    start_path = Path(os.path.join(folder_path, '.'))
    for f in start_path.glob('**/*'):
        try:
            if is_junction(f):
                continue
            if f.is_file():
                total_size += f.stat().st_size
        except (PermissionError, OSError):
            continue
    return total_size

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 19:45:05