#include "pythonhandler.h" #include #include #include PythonHandler::PythonHandler(QObject *parent) : QObject(parent) , m_initialized(false) { } PythonHandler::~PythonHandler() { finalize(); } PythonHandler *PythonHandler::getInstance() { static PythonHandler ref; return &ref; } bool PythonHandler::initialize() { if (m_initialized) { return true; } // 获取程序所在目录 QString appDir = QCoreApplication::applicationDirPath(); QString strPy= appDir + "/" + PYTHON_VER; setupEnvironment(strPy); strPy.toStdWString().c_str(); // 初始化Python解释器 Py_Initialize(); if (!Py_IsInitialized()) { qDebug() << "Python初始化失败!"; return false; } // 添加Python脚本路径 - 使用绝对路径会更可靠 QString currentPath = QCoreApplication::applicationDirPath(); QString scriptPath = currentPath + "/python_scripts"; // QString strPy= currentPath + "/" + PYTHON_VER; // QString scriptPython2 = strPy + "/DLLs"; // QString scriptPython3 = strPy + "/Lib"; // QString scriptPython4 = strPy + "/lib/site-packages"; // emit addLog(scriptPath); QString pythonCode = QString( "import sys\n" "import os\n" "sys.path.append('%1')\n" "print('========== Python 调试信息 ==========')\n" "print('当前工作目录:', os.getcwd())\n" "print('exepath:', sys.executable)\n" "print('Python 搜索路径:')\n" "for p in sys.path:\n" " print(' -', p)\n" "print('======================================')\n" ).arg(scriptPath); // emit addLog(pythonCode); PyRun_SimpleString(pythonCode.toStdString().c_str()); m_initialized = true; return true; } void PythonHandler::setupEnvironment(QString strPy) { // 使用 Qt 的方式设置环境变量 QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); // 设置 PYTHONHOME qputenv("PYTHONHOME", strPy.toLocal8Bit()); // 设置 PYTHONPATH QString pythonPath = strPy + "/Lib;" + strPy + "/lib/site-packages;" + strPy + "/DLLs;"; qputenv("PYTHONPATH", pythonPath.toLocal8Bit()); // 修改 PATH(添加程序目录) QString currentPath = QString::fromLocal8Bit(qgetenv("PATH")); QString newPath = strPy + "/DLLs;" + currentPath; qputenv("PATH", newPath.toLocal8Bit()); qDebug() << "Environment:"; qDebug() << "PYTHONHOME:" << qgetenv("PYTHONHOME"); qDebug() << "PYTHONPATH:" << qgetenv("PYTHONPATH"); } void PythonHandler::finalize() { if (m_initialized) { Py_Finalize(); m_initialized = false; } } PyObject* PythonHandler::qVariantToPythonObject(const QVariant &value) { switch (value.type()) { case QVariant::Int: return PyLong_FromLong(value.toInt()); case QVariant::Double: return PyFloat_FromDouble(value.toDouble()); case QVariant::String: return PyUnicode_FromString(value.toString().toStdString().c_str()); case QVariant::List: { QVariantList list = value.toList(); PyObject* pyList = PyList_New(list.size()); for (int i = 0; i < list.size(); ++i) { PyList_SetItem(pyList, i, qVariantToPythonObject(list[i])); } return pyList; } case QVariant::Bool: return PyBool_FromLong(value.toBool() ? 1 : 0); default: return Py_None; } } QVariant PythonHandler::pythonObjectToQVariant(PyObject *obj) { if (!obj) { qDebug() << "pythonObjectToQVariant: 输入对象为NULL"; return QVariant(); } qDebug() << "pythonObjectToQVariant: 转换类型" << Py_TYPE(obj)->tp_name; if (PyLong_Check(obj)) { long long value = PyLong_AsLongLong(obj); if (PyErr_Occurred()) { PyErr_Clear(); return QVariant(); } qDebug() << "转换为整数:" << value; return QVariant(value); } else if (PyFloat_Check(obj)) { double value = PyFloat_AsDouble(obj); qDebug() << "转换为浮点数:" << value; return QVariant(value); } else if (PyBool_Check(obj)) { bool value = (obj == Py_True); qDebug() << "转换为布尔值:" << value; return QVariant(value); } else if (PyUnicode_Check(obj)) { QString value = QString::fromUtf8(PyUnicode_AsUTF8(obj)); qDebug() << "转换为字符串:" << value; return QVariant(value); } else if (PyList_Check(obj)) { QVariantList list; Py_ssize_t size = PyList_Size(obj); qDebug() << "转换为列表,大小:" << size; for (Py_ssize_t i = 0; i < size; ++i) { PyObject* item = PyList_GetItem(obj, i); if (item) { list.append(pythonObjectToQVariant(item)); } else { list.append(QVariant()); } } return list; } else if (PyTuple_Check(obj)) { QVariantList list; Py_ssize_t size = PyTuple_Size(obj); qDebug() << "转换为元组,大小:" << size; for (Py_ssize_t i = 0; i < size; ++i) { PyObject* item = PyTuple_GetItem(obj, i); if (item) { list.append(pythonObjectToQVariant(item)); } else { list.append(QVariant()); } } return list; } else if (PyDict_Check(obj)) { QVariantMap map; PyObject* pKeys = PyDict_Keys(obj); Py_ssize_t size = PyList_Size(pKeys); qDebug() << "转换为字典,大小:" << size; for (Py_ssize_t i = 0; i < size; ++i) { PyObject* pKey = PyList_GetItem(pKeys, i); PyObject* pValue = PyDict_GetItem(obj, pKey); if (pKey && pValue && PyUnicode_Check(pKey)) { QString key = QString::fromUtf8(PyUnicode_AsUTF8(pKey)); map[key] = pythonObjectToQVariant(pValue); } } Py_DECREF(pKeys); return map; } else if (obj == Py_None) { qDebug() << "转换为None"; return QVariant(); } else { qDebug() << "未知类型,返回空QVariant"; return QVariant(); } } QString PythonHandler::capturePythonError() { QString errorMsg; PyObject *ptype, *pvalue, *ptraceback; PyErr_Fetch(&ptype, &pvalue, &ptraceback); if (pvalue) { PyObject* pstr = PyObject_Str(pvalue); if (pstr) { errorMsg = QString::fromUtf8(PyUnicode_AsUTF8(pstr)); Py_DECREF(pstr); } } // 清理 Py_XDECREF(ptype); Py_XDECREF(pvalue); Py_XDECREF(ptraceback); return errorMsg; } QVariant PythonHandler::executeScript(const QString &scriptPath, const QString &functionName, const QVariantList &args, float* outAtt0all, int nlen) { if (!m_initialized && !initialize()) { return QVariant(); } // 获取全局字典 PyObject* pModule = nullptr; PyObject* pFunc = nullptr; PyObject* pArgs = nullptr; PyObject* pResult = nullptr; QVariant result; // 导入模块 QString moduleName = scriptPath; if (moduleName.endsWith(".py")) { moduleName.chop(3); } // pModule = PyImport_ImportModule("numpy"); // if (!pModule) { // QString error = capturePythonError(); // qDebug() << "Python error:" << error; // // PyErr_Print(); // emit addLog("无法导入Python模块:" + moduleName); // return QVariant(); // } pModule = PyImport_ImportModule(moduleName.toStdString().c_str()); if (!pModule) { QString error = capturePythonError(); qDebug() << "Python error:" << error; //PyErr_Print(); emit addLog("无法导入Python模块:" + moduleName); return QVariant(); } // 获取函数 pFunc = PyObject_GetAttrString(pModule, functionName.toStdString().c_str()); if (!pFunc || !PyCallable_Check(pFunc)) { if (PyErr_Occurred()) { PyErr_Print(); } emit addLog("无法找到函数:" + functionName); Py_XDECREF(pFunc); Py_DECREF(pModule); return QVariant(); } // 构建参数 pArgs = PyTuple_New(args.size()); for (int i = 0; i < args.size(); ++i) { PyTuple_SetItem(pArgs, i, qVariantToPythonObject(args[i])); } // 调用函数 pResult = PyObject_CallObject(pFunc, pArgs); if (pResult) { if(outAtt0all) { PyObject* array1 = PyTuple_GetItem(pResult, 0); double dR = PyFloat_AsDouble(PyTuple_GetItem(pResult, 1)); // 获取double // // 将numpy数组转换为C++数组(例如使用numpy的API) // PyArrayObject* arr1 = (PyArrayObject*)PyArray_FromAny(array1, NULL, 0, 0, NPY_ARRAY_CARRAY, NULL); PyArrayObject* arr1 = (PyArrayObject*)array1; double* data1 = (double*)PyArray_DATA(arr1); int len = PyArray_DIM(arr1, 0); // 获取数组长度 if (len>nlen) len = nlen; for (int i = 0; i < len; i++) { outAtt0all[i] = data1[i]; } #ifdef _RELEASE Py_DECREF(arr1); #endif } else { result = pythonObjectToQVariant(pResult); QMap imgResult = result.toMap(); emit addLog("1#executeScript" + QString::number(imgResult.size())); } } else { PyErr_Print(); emit addLog("函数调用失败"); } #ifdef _RELEASE // 清理 Py_XDECREF(pResult); Py_XDECREF(pArgs); Py_XDECREF(pFunc); Py_XDECREF(pModule); #endif return result; } /* QVariant PythonHandler::executeScript(const QString &scriptPath, const QString &functionName, const QVariantList &args) { if (!m_initialized && !initialize()) { return QVariant(); } // 获取全局字典 PyObject* pModule = nullptr; PyObject* pFunc = nullptr; PyObject* pArgs = nullptr; PyObject* pResult = nullptr; QVariant result; // 导入模块 QString moduleName = scriptPath; if (moduleName.endsWith(".py")) { moduleName.chop(3); } pModule = PyImport_ImportModule(moduleName.toStdString().c_str()); if (!pModule) { PyErr_Print(); emit addLog("无法导入Python模块:" + moduleName); return QVariant(); } // 获取函数 pFunc = PyObject_GetAttrString(pModule, functionName.toStdString().c_str()); if (!pFunc || !PyCallable_Check(pFunc)) { if (PyErr_Occurred()) { PyErr_Print(); } emit addLog("无法找到函数:" + functionName); Py_XDECREF(pFunc); Py_DECREF(pModule); return QVariant(); } // 构建参数 pArgs = PyTuple_New(args.size()); for (int i = 0; i < args.size(); ++i) { PyTuple_SetItem(pArgs, i, qVariantToPythonObject(args[i])); } // 调用函数 pResult = PyObject_CallObject(pFunc, pArgs); if (pResult) { result = pythonObjectToQVariant(pResult); QMap imgResult = result.toMap(); emit addLog("1#executeScript" + QString::number(imgResult.size())); } else { PyErr_Print(); emit addLog("函数调用失败"); } #ifdef _RELEASE // 清理 Py_XDECREF(pResult); Py_XDECREF(pArgs); Py_XDECREF(pFunc); Py_XDECREF(pModule); #endif return result; } */ QVariant PythonHandler::executeCode(const QString &code) { if (!m_initialized && !initialize()) { return QVariant(); } PyObject* pMain = PyImport_AddModule("__main__"); PyObject* pDict = PyModule_GetDict(pMain); PyObject* pResult = PyRun_String(code.toStdString().c_str(), Py_eval_input, pDict, pDict); if (pResult) { QVariant result = pythonObjectToQVariant(pResult); Py_DECREF(pResult); return result; } else { PyErr_Print(); return QVariant(); } }