【小技巧】PyCharm建立项目,VScode+CodeX+WindowsPowerShell开发Python pyQT6

【小技巧】PyCharm建立项目,VScode+CodeX+WindowsPowerShell开发Python pyQT6
在这里插入图片描述
运行程序后,窗口如图;但是闪退。报错如下。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 是否异常

# 在项目根 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(最稳妥)

# 关掉 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-ContentOut-File 等命令;这些会把二进制覆盖成文本,立刻变成“不是有效应用程序”。

C. 再做一次最小自检(确保 PyQt 正常)

$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) 

改为:

from PyQt6.QtGui import QTextCursor self.moveCursor(QTextCursor.MoveOperation.End)# 或: cur = self.textCursor() cur.movePosition(QTextCursor.MoveOperation.End) self.setTextCursor(cur) self.ensureCursorVisible()

然后再跑:

.\.venv\Scripts\python.exe .\main.py 
在这里插入图片描述

E. 仍有问题?两个应急方案

  1. 重装一次基准 Python 3.13(64-bit)
    基准被杀软拦截/损坏时,重装可一并修复,之后再重建 .venv

用基准 Python 直跑(验证是否仅 venv 问题)

"C:\Users\CQJY\AppData\Local\Programs\Python\Python313\python.exe".\main.py 

如果缺包,就在 venv 中 pip freeze > requirements.txt,然后对基准环境 pip install -r requirements.txt --user(临时验证用)。


一句话总结

  • 这次是 .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

你的路径里有空格与括号,后续命令都要加引号并用调用运算符 &
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)

先删老的构建输出,再用“全收集”参数:

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 
PS C:\Users\xsshu\Desktop\Python\random_pro> & ".\.venv\Scripts\pyinstaller.exe" ` >> --noconfirm --clean --windowed ` >> --name RandomGame_V1.0.2 ` >> --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\asset;ui\asset" ` >> --icon ".\ui\asset\main_windows_ico_32.png" ` >> .\main.py 
解释--collect-all PyQt6 通常已足够,但个别环境里加上 --collect-submodules/--collect-data/--collect-binaries 和几个 --hidden-import 更保险。这些参数不改你源码,只是指导 PyInstaller 把 PyQt6 的包体与 Qt 插件全部打进来。构建完成后,dist\Diginv_BAT32G139\_internal\lib\PyQt6\... 就应该有了。
在这里插入图片描述


(这里基本上就打包成功了。但会遇到个图标显示的问题,参考后面的解释。)

确认 onedir 能运行后,再出 onefile:

& ".\.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(这不是改源码),内容:

# Diginv.specfrom 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')

打包:

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 当图标

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 旁,并且目标子目录名保持一致:

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 只设置前者;后者取决于运行时加载到的图片文件。

效果演示

在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

资料下载

Could not load content