【Python学习笔记】一些关于多线程,xls文件读取,PyQt5,PyInstaller打包等问题的解决方案记录

背景:

最近利用休息时间写了个小型exe程序,主要涉及的技术点有:多线程,读取xls文件,基于PyQt5的简单GUI页面,利用PyInstaller打包成exe。虽然有ChatGPT等协助,但难免还是在开发过程中遇到了一些疑难问题,所以开个记录贴刊登解决方式。

问题&解决方式:

1.PyQt+PyInstaller:tqdm报错AttributeError: ‘NoneType‘ object has no attribute ‘write‘:

这个问题我当时让GPT改了半天都没改到要点上,最后是搜索别人的贴子解决的:传送门https://blog.csdn.net/weixin_39916966/article/details/141954305?spm=1001.2014.3001.5501
在这里插入图片描述
只需加入下面的代码,把sys.stdout和sys.stderr重定向初始化就行了。

if sys.stdout is None:sys.stdout = io.StringIO()if sys.stderr is None:sys.stderr = io.StringIO()

2.PyInstaller找不到需要打包的文件路径:

在用PyInstaller打包的时候,经常会报错缺了xx依赖,导致在没有开发环境的电脑上无法运行exe程序。如果把错误发给GPT,他虽然能说出来需要什么库的什么文件,但是从电脑上找这个文件还是很费力。

于是就需要使用这个推荐工具了:Everything。传送门
https://gitcode.com/open-source-toolkit/bfdea?utm_source=highlight_word_gitcode&word=Everything
在这里插入图片描述
安装方便,搜索简单,功能强大,比电脑自带的搜索功能快了很多倍。
在这里插入图片描述
除此之外,还有一个方法,允许我们通过代码来查找目标文件路径。
例如,下面是GPT给出的参考代码,我们不知道该怎么结合自己电脑的安装情况来写打包依赖路径。

--add-data "C:/Path/To/PyQt5/Qt/plugins/platforms;platforms"

一般来说,安装了 PyQt5 后,该路径通常位于你 Python 环境的 site‑packages 下,例如:

  • 如果你使用 pip 安装,可能在 “C:\Python38\Lib\site-packages\PyQt5\Qt\plugins\platforms”
  • 如果你使用 conda 环境,可能在 “C:\Users\admin.conda\envs\Stock\Lib\site-packages\PyQt5\Qt\plugins\platforms”

如果上述这两个目录都没有的话,就可以运行下面的代码来查找实际路径:

import os
import PyQt5
print(os.path.join(os.path.dirname(PyQt5.__file__), "Qt", "plugins", "platforms"))

运行结果:
在这里插入图片描述
这个输出的路径就是你需要传递给 --add-data 参数的路径。然后你就可以把这个路径替换命令中的 “C:/Path/To/PyQt5/Qt/plugins/platforms”。

(注意,建议把路径换成正斜杠“ / ”。在 Windows 下,文件路径既可以使用正斜杠(/)也可以使用反斜杠(\)。通常建议使用正斜杠,因为反斜杠容易引起转义问题。)

3.有多种分隔符的xls表格读取:

有些表格同时存在空格、制表符等多种分隔符,可以用Sublime Text、Notepad++等软件打开,需要做一些特殊设置。
以我比较熟悉的Sublime Text为例,设置的方法如下:
在这里插入图片描述在这里插入图片描述
(说句题外话,我对Sublime Text最早的记忆是,把原神模型导入Unity玩的一个步骤,就需要用Sublime Text打开模型的一个代码文件,改一下其中一个数字,之后Unity就能正常识别模型,玩MMD了。本来想找我以前学习看的B站教程视频放在这,可惜找不到了QAQ)

有一些xls数据是混合分隔符,比如既有制表符又有空格的,就可以用正则表达式来处理,这样可以同时匹配多种分隔符。
例如,GPT生成的如下代码,可以同时匹配空格和制表符进行分割。

import re
split_data = re.split(r'\s+|\t+', data)

4.检测文件编码:

我读一个xls的时候,xlrd库,csv库,pandas库,openpyxl库都试过了,确实用尽了所有的力气和手段都没能成功,于是就决定先看看这个文件的编码是什么。
chardet库检测文件编码的代码如下:

import chardetwith open('你的文件.xls', 'rb') as f:rawdata = f.read(10000)  # 读取部分内容进行检测
result = chardet.detect(rawdata)
print(result)输出结果:{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

这段代码会输出一个字典,例如 {‘encoding’: ‘GB2312’, ‘confidence’: 0.99, …},预期就能成功得到编码答案,我发现这是一个GB2312的xls文件,那么接下来就要引出另一个问题了。

5.GB2312文件Python解析失败:“UnicodeDecodeError :‘gb2312’ codec can’t decode bytes in position 2-3:illegal multibyte sequence”:

这也是个GPT优化了半天都没突破的问题,我一开始以为是xls文件的问题,但是换了txt文件一样无法正常读取。
同样请出大神的帖子解决问题,换用兼容性更高的GB18030编码来读取:传送门
https://www.cnblogs.com/chucklu/p/16906161.html
在这里插入图片描述
以下面这段代码为例,就是可以读取GB2312的txt和xls的:

import akshare as ak
import datetime 
import pandas as pd
import chardet#uploaded_file_path = "你的txt文件路径.txt"
uploaded_file_path = "你的xls文件路径.xls"try:print("开始读取文件...")with open(uploaded_file_path, 'rb') as f:rawdata = f.read()detected_encoding = chardet.detect(rawdata)['encoding']print("检测到文件编码: " + str(detected_encoding))df = pd.read_csv(uploaded_file_path, sep="\t", header=0, encoding='GB18030', engine='python')print(df)
except Exception as e:print("读取过程出现错误: " + str(e))

6.多线程异步运行的假卡死:

我的标题这么描述可能不准确,详细情况是我的程序有多个线程,一个主线程负责图形界面的消息更新和进度展示,还有一个线程负责读取、筛选、刷新数据等。
我已经把文件无法正常读取的问题解决了,但是一点exe运行程序,正常读完文件就卡死,图形界面也没有任何输出和报异常,加了好几个测试输出的语句也都没有效果。
为此我先去仔细学习了VSCode如何调试程序,打断点查看程序运行的细节。
调试发现读取文件的问题解决了,程序里面的目标dataframe(简称df)也一直有值不是空列表,程序看着是卡死、图形界面没有输出的原因是:

  • 事件循环被阻塞:在主线程中执行耗时操作(例如循环、网络请求和 time.sleep())阻塞了 Qt 的事件循环,从而使得界面无法及时更新。
  • 输出刷新延迟:即使调用了 log_message 将输出添加到 QPlainTextEdit 中,只有当控制权返回给事件循环时,界面才会刷新显示这些内容。

因此,即便有许多输出,由于主线程被后续耗时任务占用,GUI更新就一直没有发生。

解决的办法是把耗时的任务放到子线程中运行,或者在长任务中周期性调用QApplication.processEvents() 来让界面有机会刷新(不过这种方式只是权宜之计)。
请GPT对代码作出修改,GPT采取了将耗时的任务移至子线程,并通过信号反馈日志和进度,从而避免阻塞主线程,确保图形界面能够及时刷新输出,重新运行程序,果然程序的图形界面能正常输出了。

7.本地文件的判断与读取:

这个严格来说不是我遇到的问题,而是我一个新学到的很好奇的点。托GPT的福,我的exe程序可以允许用户传入电脑本地目录的文件,我之前从来没有写过这样的功能,所以很好奇是怎么实现的。

主要使用 isLocalFile()toLocalFile() 这两个函数,他们是 Qt 框架中 QUrl 类的两个方法,用于处理 URL 数据,特别是与本地文件相关的操作。

isLocalFile():

isLocalFile() 是 QUrl 类的一个方法,用于判断一个 URL 是否指向本地文件系统中的一个文件。

  • URL(Uniform Resource Locator)有很多分类, 可以指向多种资源,包括本地文件、网络资源(如 HTTP、FTP)、以及其他协议的资源
    • 例如:
      • file:///path/to/local/file 是一个指向本地文件的 URL。
      • http://example.com/file 是一个指向网络资源的 URL。
      • ftp://example.com/file 是一个指向 FTP 服务器资源的 URL。

isLocalFile() 方法可以检查 URL 的协议(scheme是否为 file。如果是,表示该 URL 指向本地文件系统中的一个文件。它还会检查路径是否有效,确保路径是本地文件系统的一部分。

from PyQt5.QtCore import QUrlurl1 = QUrl("file:///home/user/example.xls")
url2 = QUrl("http://example.com/example.xls")print(url1.isLocalFile())  # 输出: True
print(url2.isLocalFile())  # 输出: False
toLocalFile():

toLocalFile() 是 QUrl 类的另一个方法,用于将一个指向本地文件的 URL 转换为本地文件路径。

  • URL 到路径的转换:
    • 当一个 URL 的协议为 file 时,toLocalFile() 方法会将 URL 中的路径部分提取出来,并转换为本地文件系统中的路径
    • 例如,URL file:///home/user/example.xls 会被转换为路径 /home/user/example.xls。
    • 仅适用于 file 协议的 URL,对于其他协议的 URL(如 http 或 ftp),调用 toLocalFile() 会返回空字符串
  • 路径格式化:
    • toLocalFile() 方法会根据操作系统的文件路径规则(如 Windows 使用反斜杠 \,而 Linux/Unix 使用正斜杠 /)对路径进行格式化,确保返回的路径是本地文件系统可以识别的格式
from PyQt5.QtCore import QUrlurl = QUrl("file:///home/user/example.xls")
local_path = url.toLocalFile()
print(local_path)  # 输出: /home/user/example.xls
isLocalFile() 和 toLocalFile() 的结合使用:

在实际应用中,isLocalFile() 和 toLocalFile() 通常一起使用,以确保处理的 URL 是指向本地文件的,并且能够获取到正确的本地路径。

from PyQt5.QtCore import QUrldef process_url(url):if url.isLocalFile():  # 检查是否为本地文件local_path = url.toLocalFile()  # 转换为本地路径print("本地文件路径:", local_path)# 进一步处理本地文件else:print("该 URL 不指向本地文件")# 测试
url1 = QUrl("file:///home/user/example.xls")
url2 = QUrl("http://example.com/example.xls")process_url(url1)  # 输出: 本地文件路径: /home/user/example.xls
process_url(url2)  # 输出: 该 URL 不指向本地文件

这两个方法在处理拖拽文件的场景中非常有用,因为拖拽操作可能会带来不同类型的 URL,而通过这两个方法可以确保只处理本地文件,并获取到正确的文件路径。

除了本地文件路径以外的其他url如何处理:

在 Qt 中,QUrl 提供了多种方法来检查和处理不同协议的 URL。对于 http 和 ftp 协议的 URL,虽然没有像 isLocalFile() 这样的直接方法,但可以通过以下方式实现类似的功能:

  • 如果需要检查 URL 是否为 http 或 ftp 协议,可以直接使用 scheme() 方法。
    通过比较协议字符串,可以判断 URL 是否为 http 或 ftp 协议。
QUrl url("http://example.com/file");
QString protocol = url.scheme();
if (protocol == "http") {qDebug() << "这是一个 HTTP 协议的 URL";
} else if (protocol == "ftp") {qDebug() << "这是一个 FTP 协议的 URL";
} else {qDebug() << "这是一个其他协议的 URL";
}
  • 如果需要从用户输入中解析 URL,可以使用 fromUserInput() 方法。
    如果输入的字符串类似于 http:// 或 ftp://,它会自动将其解析为对应的协议。
QUrl url = QUrl::fromUserInput("example.com");
if (url.scheme() == "http") {qDebug() << "自动解析为 HTTP 协议";
} else if (url.scheme() == "ftp") {qDebug() << "自动解析为 FTP 协议";
}
  • 结合 isValid() 方法可以进一步验证 URL 的有效性。虽然它不能直接判断协议类型,但可以结合 scheme() 方法一起使用。
QUrl url("ftp://example.com/file");
if (url.isValid() && url.scheme() == "ftp") {qDebug() << "这是一个有效的 FTP 协议 URL";
} else {qDebug() << "URL 无效或不是 FTP 协议";
}

8.输出为Excel不容易出现乱码的UTF-8-SIG编码:

这个是我从其他同学那里学来的经验,我换了台mac电脑,发现输出的UTF-8编码的csv文件在mac上打开是乱码,然后坐我旁边的同学奇迹般地把这个问题妙手回春解决了,一问,噢,他用了UTF-8-SIG编码

UTF-8-SIG 是 UTF-8 的一个变体,主要用于解决某些软件(如 Microsoft Excel)在处理 UTF-8 编码文件时可能出现的兼容性问题。

UTF-8-SIG 的好处:

  • 更好的兼容性
    在某些软件(尤其是 Microsoft 的软件,如 Excel 和 Notepad)中,UTF-8 编码的文件可能会被错误地识别为 ANSI 编码,导致乱码。
    UTF-8-SIG 文件由于包含 BOM,这些软件可以更准确地识别文件的编码格式,从而避免乱码问题。
  • 避免乱码问题
    当文件在不同系统之间传输或被不同软件打开时,UTF-8-SIG 可以减少因编码识别错误导致的乱码问题。
    在 Excel 中,使用 UTF-8-SIG 编码保存文件可以显著改善中文字符的显示效果,尤其是在处理 CSV 文件时。

如果需要确保文件在 Microsoft 软件中正确显示,建议使用 UTF-8-SIG 编码。
在 Python 中,可以使用 pandas 或 open() 函数指定编码为 utf-8-sig。
使用 pandas 保存为 UTF-8-SIG:

import pandas as pddf = pd.DataFrame({'列1': ['内容1', '内容2']})
df.to_csv('output.csv', index=False, encoding='utf-8-sig')

使用 open() 函数保存为 UTF-8-SIG:

with open('output.txt', 'w', encoding='utf-8-sig') as f:f.write('你好,世界!')

我自己的代码中,允许自定义文件名,并且保存为UTF-8-SIG的代码段:

fileName, _ = QFileDialog.getSaveFileName(self, "导出CSV", "", "CSV Files (*.csv);;All Files (*)")if fileName:try:export_df.to_csv(fileName, index=False, encoding='utf-8-sig')filename = os.path.basename(fileName)filepath = os.path.dirname(fileName)self.log_message(f"导出结果成功!文件名:{filename},保存路径:{filepath}")except Exception as e:self.log_message(f"导出结果失败:{e}")else:self.log_message("导出结果已取消")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/35253.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于javaweb的SpringBoot智能相册管理系统图片相册系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

【AI知识管理系统】(一)AI知识库工具测评

嘿,朋友们!🧐你们有没有想过,咱们平日里那些一闪而过的知识笔记、各种碎片化的idea,记录下来之后都是怎么管理的呀? 还有啊,咱们读过的那些书,大家会不会随手写点东西记录一下呢?📝要知道,如果不写的话,很可能过不了多久就全忘得一干二净啦。 😭那多年前记下的…

JVM并发编程AQSsync锁ReentrantLock线程池ThreadLocal

并发编程2 synchronized锁实现**AQS****ReentrantLock实现****JUC 常用类**池的概念 ThreadLocalThreadLocal原理内存泄露强引用:软引用弱引用虚引用ThreadLocal内存泄露 synchronized锁实现 synchronized是一个关键字,实现同步,还需要我们提供一个同步锁对象,记录锁状态,记录…

C++从入门到入土(八)——多态的原理

目录 前言 多态的原理 动态绑定与静态绑定 虚函数表 小结 前言 在前面的文章中&#xff0c;我们介绍了C三大特性之一的多态&#xff0c;我们主要介绍了多态的构成条件&#xff0c;但是对于多态的原理我们探讨的是不够深入的&#xff0c;下面这这一篇文章&#xff0c;我们将…

自带多个接口,完全免费使用!

做自媒体的小伙伴们&#xff0c;是不是经常为语音转文字的事儿头疼&#xff1f; 今天给大家推荐一款超实用的语音转文字软件——AsrTools&#xff0c;它绝对是你的得力助手&#xff01; AsrTools 免费的语音转文字软件 这款软件特别贴心&#xff0c;完全免费&#xff0c;而且操…

国内首款载重1吨级无人运输机TP1000首飞成功 2026年投入应急救援

大湾区经济网珠海快讯&#xff0c;据央视新闻报道&#xff0c;3月15日上午&#xff0c;国内首款载重1吨级大型无人运输机TP1000在山东成功首飞。该机由中国民航适航标准完全自主研发&#xff0c;起飞重量3.3吨&#xff0c;满载航程达1000公里&#xff0c;具备智能空投功能&…

设计模式Python版 访问者模式

文章目录 前言一、访问者模式二、访问者模式示例 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&#xff1a;关注类和对象之间的组…

(性能测试)性能测试工具 2.jmeter的环境搭建 3jmeter元件和4使用实例 5jmeter元件和参数化

目录 性能测试工具 性能测试工具 jemeter环境搭建 jmeter的常用目录介绍 jmeter修改语言和主题--jmeter界面的汉化 jmeter元件 jmeter元件和组件的介绍 jmeter的作用域原则 jmeter的执行顺序 案例&#xff1a;执行顺序 jmeter使用案例 jmeter线程组的介绍 jmeter…

书摘 ASP.NET Core技术内幕与项目实战:基于DDD与前后端分离

IT行业的发展瞬息万变,新技术层出不穷,很多技术人员出于个人兴趣、个人职业发展等考虑而选择一些流行的新技术,他们会把各种复杂的架构模式、高精尖的技术都加入架构中,这增加了项目的复杂度、延长了交付周期、增加了项目的研发成本。有些技术并不符合公司的情况,最后项目…

Spring Cloud 负载均衡(Ribbon)- 流量管理与服务调用优化

一、Spring Cloud Ribbon 概述 1、什么是 Spring Cloud Ribbon&#xff1f; Spring Cloud Ribbon 是一个基于客户端的负载均衡器&#xff0c;其核心目标是为微服务架构中的服务调用提供智能流量分发能力。与传统的服务端负载均衡&#xff08;如 Nginx&#xff09;不同&#x…

内网环境安装dlv,本地远程调试go

背景&#xff1a;内网环境(服务器)下安装dlv,本地通过dlv调试编译后的go代码。 可以配合观看: 【dlv远程调试-哔哩哔哩】 https://b23.tv/NqPZ5q9 内网安装dlv步骤 1、dlv安装: &#xff08;我额服务器和内网的go都是1.21以上&#xff09; # 先在有网络的环境下&#xff08…

C# MVC项目部署II后错误,403禁止访问:访问被拒绝问题处理

C# MVC项目部署II后错误&#xff0c;403禁止访问&#xff1a;访问被拒绝问题处理 问题如下&#xff1a; 解决办法&#xff1a; 1. 应用程序池要选v4.xx&#xff0c;托管模式选“集成” 2. 把asp.net 4.xx安装在iis上&#xff0c;方法&#xff1a; cd \Windows\Microsoft .NE…

基于Flask的东方财富网股票数据可视化分析系统

【大数据】基于Flask的东方财富网股票数据可视化分析系统 &#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统能够高效地从东方财富网抓取股票数据&#xff0c;并通过Python的强大数据处理能…

整形在内存中的存储(例题逐个解析)

目录 一.相关知识点 1.截断&#xff1a; 2.整形提升&#xff1a; 3.如何 截断&#xff0c;整型提升&#xff1f; &#xff08;1&#xff09;负数 &#xff08;2&#xff09;正数 &#xff08;3&#xff09;无符号整型&#xff0c;高位补0 注意&#xff1a;提升后得到的…

HarmonyOS第26天:应用发布与推广全攻略:从0到1走向市场

一、引言:开启 HarmonyOS 应用之旅 在数字化时代的浪潮中,HarmonyOS 以其独特的分布式理念和强大的跨设备协同能力,为应用开发领域开辟了一片崭新的天地。随着 HarmonyOS 市场份额的稳步增长,其生态设备数量已突破 9 亿大关,吸引了超过 254 万开发者投身其中 ,成为了开发…

【操作系统安全】任务4:Windows 系统网络安全实践里常用 DOS 命令

目录 一、引言 二、网络信息收集类命令 2.1 ipconfig 命令 2.1.1 功能概述 2.1.2 实例与代码 2.2 ping 命令 2.2.1 功能概述 2.2.2 实例与代码 2.3 tracert 命令 2.3.1 功能概述 2.3.2 实例与代码 三、网络连接与端口管理类命令 3.1 netstat 命令 3.1.1 功能概述…

《我的Python觉醒之路》之转型Python(十五)——控制流

[今天是2025年3月17日&#xff0c;继续复习第一章节、第二章节的内容 ] 《我的Python觉醒之路》之转型Python&#xff08;十四&#xff09;——控制流

通过 SVG 使用 AI 生成理想图片:技术实现与实践指南

文章目录 1. SVG 与 AI 的结合&#xff1a;技术价值2. 技术原理&#xff1a;AI 如何生成 SVG&#xff1f;3. 实现步骤&#xff1a;从需求到图形3.1 定义需求3.2 使用 AI 生成 SVG3.3 验证与调整 4. 代码解析&#xff1a;实现科技感的关键4.1 渐变背景4.2 网格线条4.3 发光六边形…

OpenCV计算摄影学(22)将输入的彩色图像转换为两种风格的铅笔素描效果函数pencilSketch()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 铅笔风格非写实线描图。 该函数通过图像处理技术将输入的彩色图像转换为两种风格的铅笔素描效果&#xff1a; dst1&#xff1a;炭笔效果的灰度图…

JavaScript运算符与流程控制详解

一、运算符 • 赋值运算符 • 一元运算符 • 比较运算符 • 逻辑运算符 • 运算符优先级 1.算术运算符 数字是用来计算的&#xff0c;比如&#xff1a;乘法 * 、除法 / 、加法 、减法 - 等等&#xff0c;所以经常和算术运算符一起。 算术运算符&#xff1a;也叫数学运算符&…