|
|
|
|
@ -0,0 +1,237 @@
|
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
"""
|
|
|
|
|
完整的PyQt5问题解决方案
|
|
|
|
|
运行此脚本可以完全避免PyQt5平台插件问题
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import subprocess
|
|
|
|
|
import sys
|
|
|
|
|
import os
|
|
|
|
|
import shutil
|
|
|
|
|
import platform
|
|
|
|
|
|
|
|
|
|
def run_command(cmd, description):
|
|
|
|
|
"""运行命令并显示进度"""
|
|
|
|
|
print(f"正在执行: {description}")
|
|
|
|
|
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
|
|
|
if result.returncode != 0:
|
|
|
|
|
print(f"❌ 失败: {result.stderr}")
|
|
|
|
|
return False
|
|
|
|
|
print(f"✅ 完成")
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def clean_pyqt5_installation():
|
|
|
|
|
"""彻底清理PyQt5安装"""
|
|
|
|
|
print("=== 清理PyQt5安装 ===")
|
|
|
|
|
|
|
|
|
|
# 1. 卸载PyQt5包
|
|
|
|
|
run_command([sys.executable, "-m", "pip", "uninstall", "PyQt5", "PyQt5-Qt5", "PyQt5-sip", "-y"],
|
|
|
|
|
"卸载PyQt5包")
|
|
|
|
|
|
|
|
|
|
# 2. 清理残留文件
|
|
|
|
|
venv_path = os.environ.get('VIRTUAL_ENV', '')
|
|
|
|
|
if venv_path:
|
|
|
|
|
site_packages = os.path.join(venv_path, 'lib', f'python{sys.version_info.major}.{sys.version_info.minor}', 'site-packages')
|
|
|
|
|
if os.path.exists(site_packages):
|
|
|
|
|
removed_count = 0
|
|
|
|
|
for item in os.listdir(site_packages):
|
|
|
|
|
if 'pyqt5' in item.lower():
|
|
|
|
|
item_path = os.path.join(site_packages, item)
|
|
|
|
|
try:
|
|
|
|
|
if os.path.isdir(item_path):
|
|
|
|
|
shutil.rmtree(item_path)
|
|
|
|
|
else:
|
|
|
|
|
os.remove(item_path)
|
|
|
|
|
removed_count += 1
|
|
|
|
|
print(f" 删除: {item}")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f" 删除失败 {item}: {e}")
|
|
|
|
|
print(f"✅ 清理完成,删除了 {removed_count} 个项目")
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def install_pyqt5_properly():
|
|
|
|
|
"""正确安装PyQt5"""
|
|
|
|
|
print("=== 安装PyQt5 ===")
|
|
|
|
|
|
|
|
|
|
# 使用清华镜像源加速下载(可选)
|
|
|
|
|
pip_args = [sys.executable, "-m", "pip", "install"]
|
|
|
|
|
|
|
|
|
|
# 检查是否有国内镜像源可用
|
|
|
|
|
try:
|
|
|
|
|
import requests
|
|
|
|
|
response = requests.get("https://pypi.tuna.tsinghua.edu.cn/simple", timeout=5)
|
|
|
|
|
if response.status_code == 200:
|
|
|
|
|
pip_args.extend(["-i", "https://pypi.tuna.tsinghua.edu.cn/simple"])
|
|
|
|
|
print("使用清华镜像源")
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# 安装PyQt5
|
|
|
|
|
pip_args.extend(["PyQt5==5.15.10", "--no-cache-dir", "--force-reinstall"])
|
|
|
|
|
|
|
|
|
|
return run_command(pip_args, "安装PyQt5")
|
|
|
|
|
|
|
|
|
|
def setup_environment_variables():
|
|
|
|
|
"""设置环境变量"""
|
|
|
|
|
print("=== 设置环境变量 ===")
|
|
|
|
|
|
|
|
|
|
system = platform.system()
|
|
|
|
|
venv_path = os.environ.get('VIRTUAL_ENV', '')
|
|
|
|
|
|
|
|
|
|
if not venv_path:
|
|
|
|
|
print("❌ 未检测到虚拟环境")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
python_version = f"python{sys.version_info.major}.{sys.version_info.minor}"
|
|
|
|
|
|
|
|
|
|
# 可能的Qt插件路径
|
|
|
|
|
possible_paths = []
|
|
|
|
|
|
|
|
|
|
if system == "Darwin": # macOS
|
|
|
|
|
possible_paths = [
|
|
|
|
|
os.path.join(venv_path, 'lib', python_version, 'site-packages', 'PyQt5', 'Qt5', 'plugins'),
|
|
|
|
|
'/usr/local/opt/qt5/plugins',
|
|
|
|
|
'/opt/homebrew/opt/qt5/plugins',
|
|
|
|
|
]
|
|
|
|
|
elif system == "Windows":
|
|
|
|
|
possible_paths = [
|
|
|
|
|
os.path.join(venv_path, 'Lib', 'site-packages', 'PyQt5', 'Qt5', 'plugins'),
|
|
|
|
|
]
|
|
|
|
|
elif system == "Linux":
|
|
|
|
|
possible_paths = [
|
|
|
|
|
os.path.join(venv_path, 'lib', python_version, 'site-packages', 'PyQt5', 'Qt5', 'plugins'),
|
|
|
|
|
'/usr/lib/x86_64-linux-gnu/qt5/plugins',
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
# 找到有效的路径
|
|
|
|
|
valid_path = None
|
|
|
|
|
for path in possible_paths:
|
|
|
|
|
if os.path.exists(path) and os.path.exists(os.path.join(path, 'platforms')):
|
|
|
|
|
valid_path = path
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
if valid_path:
|
|
|
|
|
# 创建环境变量设置脚本
|
|
|
|
|
env_script = f"""
|
|
|
|
|
# PyQt5环境变量设置
|
|
|
|
|
export QT_PLUGIN_PATH="{valid_path}"
|
|
|
|
|
export QT_QPA_PLATFORM_PLUGIN_PATH="{os.path.join(valid_path, 'platforms')}"
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
if system == "Darwin":
|
|
|
|
|
env_script += """
|
|
|
|
|
export QT_QPA_PLATFORM="cocoa"
|
|
|
|
|
export QT_MAC_WANTS_LAYER="1"
|
|
|
|
|
export QT_LOGGING_RULES="qt.qpa.*=false"
|
|
|
|
|
"""
|
|
|
|
|
elif system == "Windows":
|
|
|
|
|
env_script += """
|
|
|
|
|
export QT_QPA_PLATFORM="windows"
|
|
|
|
|
"""
|
|
|
|
|
elif system == "Linux":
|
|
|
|
|
env_script += """
|
|
|
|
|
export QT_QPA_PLATFORM="xcb"
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# 保存环境变量脚本
|
|
|
|
|
project_root = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
env_file = os.path.join(project_root, 'set_pyqt5_env.sh')
|
|
|
|
|
with open(env_file, 'w') as f:
|
|
|
|
|
f.write(env_script.strip())
|
|
|
|
|
|
|
|
|
|
print(f"✅ 环境变量脚本已创建: {env_file}")
|
|
|
|
|
print(f" QT_PLUGIN_PATH: {valid_path}")
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
print("❌ 未找到有效的Qt插件路径")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def verify_installation():
|
|
|
|
|
"""验证安装"""
|
|
|
|
|
print("=== 验证安装 ===")
|
|
|
|
|
|
|
|
|
|
# 测试导入
|
|
|
|
|
test_code = """
|
|
|
|
|
import sys
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
# 设置环境变量
|
|
|
|
|
if 'QT_PLUGIN_PATH' in os.environ:
|
|
|
|
|
os.environ['QT_PLUGIN_PATH'] = os.environ['QT_PLUGIN_PATH']
|
|
|
|
|
if 'QT_QPA_PLATFORM_PLUGIN_PATH' in os.environ:
|
|
|
|
|
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = os.environ['QT_QPA_PLATFORM_PLUGIN_PATH']
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
from PyQt5.QtWidgets import QApplication, QLabel
|
|
|
|
|
from PyQt5.QtCore import Qt
|
|
|
|
|
|
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
|
label = QLabel("PyQt5安装成功!✅")
|
|
|
|
|
label.setAlignment(Qt.AlignCenter)
|
|
|
|
|
label.resize(200, 100)
|
|
|
|
|
label.show()
|
|
|
|
|
|
|
|
|
|
# 只显示2秒后自动关闭
|
|
|
|
|
from PyQt5.QtCore import QTimer
|
|
|
|
|
QTimer.singleShot(2000, app.quit)
|
|
|
|
|
|
|
|
|
|
app.exec_()
|
|
|
|
|
print("✅ PyQt5验证成功!")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"❌ PyQt5验证失败: {e}")
|
|
|
|
|
import traceback
|
|
|
|
|
traceback.print_exc()
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
with open('test_pyqt5.py', 'w') as f:
|
|
|
|
|
f.write(test_code)
|
|
|
|
|
|
|
|
|
|
result = subprocess.run([sys.executable, 'test_pyqt5.py'], capture_output=True, text=True)
|
|
|
|
|
|
|
|
|
|
# 清理测试文件
|
|
|
|
|
if os.path.exists('test_pyqt5.py'):
|
|
|
|
|
os.remove('test_pyqt5.py')
|
|
|
|
|
|
|
|
|
|
return result.returncode == 0
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
"""主函数"""
|
|
|
|
|
print("=== PyQt5完整修复方案 ===")
|
|
|
|
|
print(f"系统: {platform.system()}")
|
|
|
|
|
print(f"Python: {sys.version}")
|
|
|
|
|
print(f"虚拟环境: {os.environ.get('VIRTUAL_ENV', '未激活')}")
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
# 获取项目根目录
|
|
|
|
|
project_root = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
os.chdir(project_root)
|
|
|
|
|
|
|
|
|
|
steps = [
|
|
|
|
|
("清理安装", clean_pyqt5_installation),
|
|
|
|
|
("重新安装", install_pyqt5_properly),
|
|
|
|
|
("设置环境", setup_environment_variables),
|
|
|
|
|
("验证安装", verify_installation),
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
success = True
|
|
|
|
|
for step_name, step_func in steps:
|
|
|
|
|
if not step_func():
|
|
|
|
|
print(f"❌ {step_name} 失败")
|
|
|
|
|
success = False
|
|
|
|
|
break
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
if success:
|
|
|
|
|
print("🎉 PyQt5修复完成!")
|
|
|
|
|
print("\n使用方法:")
|
|
|
|
|
print("1. 运行: source set_pyqt5_env.sh")
|
|
|
|
|
print("2. 然后运行: python src/main.py")
|
|
|
|
|
else:
|
|
|
|
|
print("❌ PyQt5修复失败,请检查错误信息")
|
|
|
|
|
|
|
|
|
|
return success
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
success = main()
|
|
|
|
|
sys.exit(0 if success else 1)
|