
运行程序后,窗口如图;但是闪退。报错如下。C:\Users\CQJY\Desktop\PythonProject.venv\Scripts\python.exe C:\Users\CQJY\Desktop\PythonProject\main.py 进程已结束,退出代码为 -1073740791 (0xC0000409)

现在这个新报错:
程序"python.exe"无法运行: 指定的可执行文件不是此操作系统平台的有效应用程序。
几乎可以肯定是 .venv\Scripts\python.exe 被破坏/替换 (或和基准 Python 不一致)。之前它还能跑、能弹 "Qt ok",说明不是系统位数问题,而是后来 venv 里的 python.exe 损坏了 (最常见是误用 Set-Content、杀毒拦截/隔离、或复制覆盖)。
按下面做,最快恢复:
A. 对比一下:venv 的 python.exe 是否异常
powershell
# 在项目根
cd C:\Users\CQJY\Desktop\PythonProject
# 看大小与版本信息
(Get-Item .\.venv\Scripts\python.exe).Length
(Get-Item .\.venv\Scripts\python.exe).VersionInfo | fl ProductVersion,FileVersion
# 与基准 Python 对比(应接近相同)
(Get-Item "C:\Users\CQJY\AppData\Local\Programs\Python\Python313\python.exe").Length
如果 venv 里的体积很小/为 0 或与基准差异巨大,就是被破坏了。
B. 直接重建 .venv(最稳妥)
powershell
# 关掉 PyCharm,避免占用 .venv
cd C:\Users\CQJY\Desktop\PythonProject
Remove-Item -Recurse -Force .\.venv
# 用你已安装的 3.13/64 重建
py -3.13 -m venv .venv
# 快速自检
.\.venv\Scripts\python.exe -V
.\.venv\Scripts\python.exe -c "import struct,platform;print('arch=',struct.calcsize('P')*8,'os=',platform.platform())"
# 重新装依赖
.\.venv\Scripts\python.exe -m pip install -U pip
.\.venv\Scripts\python.exe -m pip install PyQt6 pyserial # 串口建议用 pyserial,更稳
⚠️ 小心别再对可执行文件用
Set-Content、Out-File等命令;这些会把二进制覆盖成文本,立刻变成"不是有效应用程序"。
C. 再做一次最小自检(确保 PyQt 正常)
powershell
$probe = @'
from PyQt6.QtWidgets import QApplication, QWidget
import sys
app = QApplication(sys.argv)
w = QWidget(); w.setWindowTitle("probe"); w.show()
print("Qt ok")
sys.exit(app.exec())
'@
Set-Content -Path .\_qt_probe.py -Value $probe -Encoding UTF8
.\.venv\Scripts\python.exe .\_qt_probe.py
D. 跑你的项目前,记得修掉上一个 PyQt6 兼容问题
你之前的异常在:
ui\widgets.py:177 -> self.moveCursor(self.textCursor().End)
改为:
python
from PyQt6.QtGui import QTextCursor
self.moveCursor(QTextCursor.MoveOperation.End)
# 或:
cur = self.textCursor()
cur.movePosition(QTextCursor.MoveOperation.End)
self.setTextCursor(cur)
self.ensureCursorVisible()
然后再跑:
powershell
.\.venv\Scripts\python.exe .\main.py

E. 仍有问题?两个应急方案
-
用基准 Python 直跑(验证是否仅 venv 问题)
powershell"C:\Users\CQJY\AppData\Local\Programs\Python\Python313\python.exe" .\main.py如果缺包,就在 venv 中
pip freeze > requirements.txt,然后对基准环境pip install -r requirements.txt --user(临时验证用)。 -
重装一次基准 Python 3.13(64-bit)
基准被杀软拦截/损坏时,重装可一并修复,之后再重建
.venv。
一句话总结
- 这次是
.venv\Scripts\python.exe被破坏 导致的"不是有效应用程序"。 - 删除
.venv→ 重建 → 重新装依赖 就能恢复;随后把上次的 QTextCursor 写法改掉,程序应能正常运行。 - 以后只对 .py 文件 用
Set-Content;不要 对.exe/.dll之类二进制用这些命令。
20251107
打包成功后双击exe文件会有这个弹窗报错。

报错窗口里写得很直白:No module named 'PyQt6'。
意思是打包产物里没把 PyQt6 包进去 (或运行时没能找到它),所以 exe 一启动、执行到 import PyQt6 就挂了。
最常见原因与修法👇(按顺序做,基本一次好):
0)快速确认问题点
在 dist 目录里看一眼(你现在是 onedir 形态,PyInstaller 6.x 会把内容放到 _internal 子目录里):
- 应该能看到:
dist\Diginv_BAT32G139\_internal\lib\PyQt6\__init__.py等一堆文件/Qt 插件目录。 - 如果 没有
PyQt6这个目录,就印证了:打包时没收进去。
1)确认你用的是项目 venv里的 Python,且里面有 PyQt6
你的路径里有空格与括号,后续命令都要加引号 并用调用运算符
&。
powershell
cd "C:\Users\CQJY\Desktop\PythonProject_20251106_14_30 V1.1.3(阶段性成功)"
# 1) 这个 python 应该是你项目的 .venv
& ".\.venv\Scripts\python.exe" -c "import sys; print(sys.executable)"
# 2) 这里必须能 import PyQt6(否则先安装)
& ".\.venv\Scripts\python.exe" -c "import PyQt6, sys; print('OK:', PyQt6.__file__)"
# 若报错,再装:
& ".\.venv\Scripts\python.exe" -m pip install -U PyQt6
如果上一步 OK,说明你的构建环境有 PyQt6,继续第 2 步。
2)清理后用更稳的打包命令重建(收全 PyQt6)
先删老的构建输出,再用"全收集"参数:
powershell
Remove-Item -Recurse -Force .\build, .\dist, .\Diginv*.spec -ErrorAction SilentlyContinue
& ".\.venv\Scripts\python.exe" -m pip install -U "pyinstaller>=6.7"
# onedir(便于检查)
& ".\.venv\Scripts\pyinstaller.exe" `
--noconfirm --clean --windowed `
--name Diginv_BAT32G139 `
--collect-all PyQt6 `
--collect-submodules PyQt6 `
--collect-data PyQt6 `
--collect-binaries PyQt6 `
--hidden-import PyQt6 `
--hidden-import PyQt6.QtWidgets `
--hidden-import PyQt6.QtCore `
--hidden-import PyQt6.QtGui `
--hidden-import PyQt6.QtSerialPort `
--add-data ".\ui\assets;ui\assets" `
--icon ".\ui\assets\app.ico" `
.\main.py
解释
--collect-all PyQt6通常已足够,但个别环境里加上--collect-submodules/--collect-data/--collect-binaries和几个--hidden-import更保险。- 这些参数不改你源码,只是指导 PyInstaller 把 PyQt6 的包体与 Qt 插件全部打进来。
- 构建完成后,
dist\Diginv_BAT32G139\_internal\lib\PyQt6\...就应该有了。

(这里基本上就打包成功了。但会遇到个图标显示的问题,参考后面的解释。)
确认 onedir 能运行后,再出 onefile:
powershell
& ".\.venv\Scripts\pyinstaller.exe" `
--noconfirm --clean --windowed --onefile `
--name Diginv_BAT32G139 `
--collect-all PyQt6 `
--collect-submodules PyQt6 `
--collect-data PyQt6 `
--collect-binaries PyQt6 `
--hidden-import PyQt6 `
--hidden-import PyQt6.QtWidgets `
--hidden-import PyQt6.QtCore `
--hidden-import PyQt6.QtGui `
--hidden-import PyQt6.QtSerialPort `
--add-data ".\ui\assets;ui\assets" `
--icon ".\ui\assets\app.ico" `
.\main.py
3)若仍出同样错,用 spec 文件"锁死"收集规则
在项目根新建 Diginv.spec(这不是改源码),内容:
python
# Diginv.spec
from PyInstaller.utils.hooks import collect_submodules, collect_data_files, collect_dynamic_libs
hiddenimports = collect_submodules('PyQt6')
datas = collect_data_files('PyQt6')
binaries = collect_dynamic_libs('PyQt6')
# 带上你的资源
datas += [('ui/assets', 'ui/assets')]
block_cipher = None
a = Analysis(
['main.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
runtime_hooks=[],
excludes=[],
noarchive=False
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz, a.scripts, a.binaries, a.zipfiles, a.datas,
name='Diginv_BAT32G139',
console=False, # windowed
icon='ui/assets/app.ico'
)
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, name='Diginv_BAT32G139')
打包:
powershell
Remove-Item -Recurse -Force .\build, .\dist -ErrorAction SilentlyContinue
& ".\.venv\Scripts\pyinstaller.exe" .\Diginv.spec
4)其他容易忽略的小坑
- 用错解释器 :务必用
& ".\.venv\Scripts\pyinstaller.exe",别用全局 pyinstaller。 - PyInstaller 版本:建议 ≥ 6.7(对 Python 3.13 与新打包结构更稳)。
- 路径/权限 :尽量避免将 dist 放在受限目录下,或被杀软清空
_internal。 - 杀软误杀:onefile 形态解压到临时目录时容易被拦;先用 onedir 验证,再考虑发布 onefile 或让对方加白名单。
复盘你这次的现象
- dist 里只有一个
exe+_internal文件夹、但运行提示找不到 PyQt6 → 基本就是_internal\lib里没 PyQt6 包(或被杀软删了)。 - 通过上面"全收集 + 清理重打"的命令,通常一次解决。
- 打好 onedir 后,先确认
_internal\lib\PyQt6是否存在,再双击运行。
需要的话,你把 构建日志 里关于 PyQt6 的几行(WARNING: Hidden import not found 之类)贴出来,我可以据此最小化参数(把多余的 --hidden-import 去掉),保证以后打包命令更干净。
在执行2)清理后用更稳的打包命令重建(收全 PyQt6)的时候报错:

报错的意思是:你传给 --icon 的那个 app.ico 不是一个符合要求的 Windows ICO (很可能是 PNG 改后缀、或只包含 PNG-压缩的条目、或文件损坏)。在 Windows 上 PyInstaller 只接受 .ico 或 .exe 的图标资源。如果安装了 Pillow,它可以把 PNG 等自动转成合规 ICO;否则就抛出你看到的错误。
给你三个"立刻可用"的修法,任选其一就能过去(都不改你项目源码)。
方案 A:安装 Pillow,然后直接用 PNG 当图标
powershell
cd "C:\Users\CQJY\Desktop\PythonProject_20251106_14_30 V1.1.3(阶段性成功)"
& ".\.venv\Scripts\python.exe" -m pip install -U pillow
# 重新打包时把 --icon 指向 PNG(PyInstaller 会借助 Pillow 自动转成 .ico)
确保
.\ui\assets\app.png存在,最好是正方形 256×256 带透明背景。

如图所示,为什么不打包单独运行main.py的时候主页左上角的图标正常显示,但是打包exe文件后,可执行文件的logo是有了,但是进入主页的左上角图标没有了。

原因很简单:
Explorer 里看到的 exe 图标 是 --icon 给 exe 设置的"文件图标";
窗口左上角的图标 是你的代码里 setWindowIcon(QIcon("...")) 去加载的运行时图片文件 。
打包后,这个图片没有出现在 exe 运行目录的预期位置 (或被放进 _internal/临时目录里,程序用相对路径找不到),于是窗口就显示成默认的小白框。
你截图里的 onedir 产物里,exe 旁边只有 _internal,没有 ui\assets\... ,说明 --add-data 并没把资源放到你代码期望的相对路径。
立刻可用的两种修法(不改任何源码)
方案 A:把资源按"原相对路径"放到 exe 旁(推荐)
清理后重打,确保把 ui\assets 整个目录复制到 exe 旁,并且目标子目录名保持一致:
powershell
cd "C:\Users\CQJY\Desktop\PythonProject_20251106_14_30 V1.1.3(阶段性成功)"
Remove-Item -Recurse -Force .\build, .\dist, .\Diginv*.spec -ErrorAction SilentlyContinue
# 用项目 venv 的 PyInstaller
& ".\.venv\Scripts\python.exe" -m pip install -U pyinstaller
# onedir(便于检查)
& ".\.venv\Scripts\pyinstaller.exe" `
--noconfirm --clean --windowed `
--name Diginv_BAT32G139 `
--collect-all PyQt6 `
--add-data "ui\assets;ui\assets" ` # ← 关键:把整个 ui\assets 带到 dist\...\ui\assets
--icon "ui\assets\app.ico" `
.\main.py
打完后检查:
dist\Diginv_BAT32G139\
Diginv_BAT32G139.exe
ui\assets\app.ico ← 必须存在
ui\assets\...其他图片...
_internal\...
现在双击运行,窗口左上角图标应恢复正常。
注意:
- 在 PowerShell 里,
--add-data的分隔符是;(我们已用对了);- 不要写成
".\ui\assets;ui\assets"也没问题,但更稳的是去掉.\直接用相对路径"ui\assets;ui\assets";- 若你只想带单个文件,也可以多写几条:
--add-data "ui\assets\app.png;ui\assets" --add-data "ui\assets\app.ico;ui\assets"
方案 B:直接把资源手动拷到 exe 旁
不想重打也行:把你项目里的 ui\assets 整个文件夹手动复制到
dist\Diginv_BAT32G139\ui\assets\
保证文件名/相对路径与源码一致(比如源码里写的是 ui/assets/app.png 就要有这条路径)。再次运行,窗口图标立即正常。
为什么单独 python main.py 正常、打包后不正常?
- 你在源码环境下的工作目录 正好就是项目根,
ui/assets/...能被找到; - 打包后(尤其 PyInstaller 6.x 的 onedir 新布局),很多文件被放进
_internal;如果你没把资源复制到 exe 旁的相同相对路径,QIcon("ui/assets/...")找不到文件,Qt 不会抛异常,只是静默失败显示默认图标。
想发 onefile 也保留原相对路径(仍然不改源码)?
onefile 会把资源解压到临时目录,与你的相对路径不一致;在不改源码的前提下,建议:
- 对外发 onedir 版本(最稳);
- 或发 onefile 的同时 附带一个
ui\assets文件夹(但这就不是纯单文件了)。
真要 onefile 且纯单文件,就需要在代码里用
sys._MEIPASS定位解包目录------这就属于"改源码",与你当前约束冲突。
小结
- 你现在的问题是资源未在预期路径。
- 解决:用
--add-data "ui\assets;ui\assets"让打包产物中出现dist\...\ui\assets\...;或手工把该目录拷到 exe 旁。 - exe 的"文件图标"与窗口图标是两回事:
--icon只设置前者;后者取决于运行时加载到的图片文件。
效果演示

