我在c++代码里调用python的脚本.使用接口PyImport_Import import的是一个存粹的python的脚本可以成功,但是如果import的是pyqt的脚本,就会失败
maoliangwu opened this issue · 5 comments
Environment : / 环境
- OS: Win 10
- Python 3.7.9 x86
- PyQt5 PyQt5_Qt5-5.15.2
我有两个脚本一个是test.py
def fun():
print("Something that provides mirth or amusement")
另一个是hellopyqt.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
def fun():
app = QApplication(sys.argv)
widget = QWidget()
textLabel = QLabel(widget)
textLabel.setText("Hello World!")
textLabel.move(110,85)
widget.setGeometry(50,50,320,200)
widget.setWindowTitle("PyQt5 Example")
widget.show()
sys.exit(app.exec_())
#if name == 'main':
fun()
我在qtcreator中创建了一个c++的qt工程
主要是用来加载py模块,调用Py脚本中的方法。
当我import “test.py”的时候PyImport_Import可以返回正确的值,但是如果import的是pyqt的那个脚本“hellopyqt.py”时,接口返回的时null。
我的两个脚本直接双击运行都时没有问题的。
我在电脑上已经安装了pyqt5 C:\Users**\AppData\Local\Programs\Python\Python37-32\Lib\site-packages
并且我已经添加了环境变量
PYTHONPATH = C:\Users*\AppData\Local\Programs\Python\Python37-32\Lib\site-packages
project url:https://github.com/maoliangwu/c-call-pyqt
你可能还需要设置qt相关的路径
from distutils.sysconfig import get_python_lib
libpath = get_python_lib()
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = os.path.join(
libpath, 'PyQt5', 'Qt', 'plugins', 'platforms')
os.environ['QML_IMPORT_PATH'] = os.path.join(libpath, 'Qt', 'qml')
os.environ['QML2_IMPORT_PATH'] = os.environ['QML_IMPORT_PATH']
if os.name == 'nt':
os.environ['PATH'] = os.path.join(
libpath, 'PyQt5', 'Qt', 'bin') + os.pathsep + os.environ['PATH']
os.environ['PATH'] = os.path.dirname(
os.path.abspath(sys.argv[0])) + os.pathsep + os.environ['PATH']
print(os.environ['PATH'])
另外晚点我发下之前PyQtClient里面编译的启动exe里面的源码
或者还有个工具交pybind11 很方便c++调用py(可能也需要设置Qt相关变量)
你可能还需要设置qt相关的路径
from distutils.sysconfig import get_python_lib libpath = get_python_lib() os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = os.path.join( libpath, 'PyQt5', 'Qt', 'plugins', 'platforms') os.environ['QML_IMPORT_PATH'] = os.path.join(libpath, 'Qt', 'qml') os.environ['QML2_IMPORT_PATH'] = os.environ['QML_IMPORT_PATH'] if os.name == 'nt': os.environ['PATH'] = os.path.join( libpath, 'PyQt5', 'Qt', 'bin') + os.pathsep + os.environ['PATH'] os.environ['PATH'] = os.path.dirname( os.path.abspath(sys.argv[0])) + os.pathsep + os.environ['PATH'] print(os.environ['PATH'])
另外晚点我发下之前PyQtClient里面编译的启动exe里面的源码
或者还有个工具交pybind11 很方便c++调用py(可能也需要设置Qt相关变量)
在脚本里加了你说的这段代码,但是没有用,奇怪,这个脚本单独运行是没有问题的。但是用c的接口调用就不行。感觉确实是可能哪里环境没有配置好,而且发现跟pyqt好像也没关系,如果我import了site-package里面的一些其他的包,也可能会出现这个问题
那就是python环境变量的问题
PYTHONPATH
PYTHONHOME
等等
比如参考linux下的设置
export PYTHONHOME=当前路径
export PYTHONPATH=当前路径/python3.6/:当前路径/python3.6/dlls/:当前路径/python3.6/site-packages/:当前路径/python3.6/site-packages/
另外也可以通过在代码里import sys添加
最简单的可以用 pybind11
比如:https://blog.csdn.net/thisisfangsheng/article/details/75610558
你可能还需要设置qt相关的路径
from distutils.sysconfig import get_python_lib libpath = get_python_lib() os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = os.path.join( libpath, 'PyQt5', 'Qt', 'plugins', 'platforms') os.environ['QML_IMPORT_PATH'] = os.path.join(libpath, 'Qt', 'qml') os.environ['QML2_IMPORT_PATH'] = os.environ['QML_IMPORT_PATH'] if os.name == 'nt': os.environ['PATH'] = os.path.join( libpath, 'PyQt5', 'Qt', 'bin') + os.pathsep + os.environ['PATH'] os.environ['PATH'] = os.path.dirname( os.path.abspath(sys.argv[0])) + os.pathsep + os.environ['PATH'] print(os.environ['PATH'])
另外晚点我发下之前PyQtClient里面编译的启动exe里面的源码
或者还有个工具交pybind11 很方便c++调用py(可能也需要设置Qt相关变量)
好的,我周末试试pybind11。关于前面的哪个问题,我发现是pyqt的py文件后缀是pyi,当我使用c接口PyImport_Import传入hellopyqt.py,提示的错误是找不到PyQt5.QtWidgets,我把site-packages里面的PyQt5里面的QtWidgets.pyi改名位QtWidgets.py。去掉了最后一个i以后它就不再报找不到模块的这个问题了。这个是什么缘故,你知道吗
在初始化解释器前需要设置一些三方库路径,比如:
Py_SetPythonHome((wchar_t*)(L"./"));
Py_SetPath(L"DLLs;python35.zip;Lib;Lib/site-packages"); //设置库
Py_Initialize();
可以查一下这方面的资料