#include "PythonQtLoader.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include "QT_ClientCtrl.h"
#include "QT_ServerModel.h"
#include "QTW_Maintain.h"
#include "QTW_Manage.h"
PythonQtLoader* g_pPythonQtLoader;
void ReorganizePythonVersion(QList& _listVer, QMap& _mapVer, const TPythonVer& _PriorityVersion)
{
//妿æå®äºä¼å
使ç¨ççæ¬ï¼é£å°±æå®æ¾æåé¢ï¼ç¶åæçæ¬å·ä»å¤§å°å°é¡ºåºæ¾å
¥
if (!_PriorityVersion.MajorVersion.isEmpty())
{
QMap::iterator t_iter = _mapVer.find(_PriorityVersion);
if (t_iter != _mapVer.end())
{
_listVer.append(t_iter.key());
_mapVer.erase(t_iter);
}
}
for (QMap::iterator i = --_mapVer.end(); i != --_mapVer.begin(); --i)
{
_listVer.append(i.key());
}
}
#if defined(Q_OS_WIN)
void PythonQtLoader::FindPythonVersion(QList& _listVer)
{
_listVer.clear();
QMap t_mapVer; //QSet好ååªæ¯æHASHï¼ä¸æ¯æèªå®ä¹æ¯è¾å½æ°
QProcessEnvironment t_SysEnvironment = QProcessEnvironment::systemEnvironment();
QString t_Paths = t_SysEnvironment.value("PATH");
QStringList t_PathList = t_Paths.split(";", Qt::SkipEmptyParts);
//妿æå®äºhomeè·¯å¾ï¼åä¼å
æ¾è¿ä¸ª
if (!m_PythonHome.isEmpty())
t_PathList.append(m_PythonHome);
QString t_DebugExt = "";
#ifndef NDEBUG
t_DebugExt = "_d";
#endif
QString t_PythonQtName = QString("python*.dll");
QRegExp t_PythonQtNameReg(QString("python([0-9])([0-9]+)%1").arg(t_DebugExt));
foreach(QString t_Path, t_PathList)
{
QFileInfoList t_FileInfos = QDir(t_Path).entryInfoList(QStringList() << t_PythonQtName, QDir::Files);
foreach(QFileInfo t_FileInfo, t_FileInfos)
{
if (!QLibrary::isLibrary(t_FileInfo.absoluteFilePath()))
continue;
QString t_CompleteBaseName = t_FileInfo.completeBaseName();
if (t_PythonQtNameReg.indexIn(t_CompleteBaseName) == -1)
continue;
TPythonVer t_PythonVer(t_PythonQtNameReg.cap(1), t_PythonQtNameReg.cap(2));
//ç¸åçæ¬åªä¿çæåé¢çé£ä¸ª
if (t_mapVer.find(t_PythonVer) != t_mapVer.end())
continue;
//windowsä¸ï¼PythonHomeå°±æ¯åºæä»¶æå¨ç®å½
t_PythonVer.path = QDir(t_Path).absolutePath();
t_mapVer.insert(t_PythonVer, 0);
qDebug() << "find python ver:" << t_PythonVer.MajorVersion << "." << t_PythonVer.MinorVersion;
}
}
ReorganizePythonVersion(_listVer, t_mapVer, m_PriorityVersion);
}
#elif defined(Q_OS_LINUX)
void PythonQtLoader::FindPythonVersion(QList& _listVer)
{
_listVer.clear();
QMap t_mapVer;
QProcess t_ldconfig;
t_ldconfig.start("ldconfig", QStringList() << "-p");
t_ldconfig.waitForFinished();
QString t_out = QString(t_ldconfig.readAllStandardOutput());
//QFile t_file("z:/ldconfig-p.txt");
//t_file.open(QIODevice::ReadOnly | QIODevice::Text);
//QString t_out = QString(t_file.readAll());
QStringList t_lines = t_out.split('\n', Qt::SkipEmptyParts);
QRegExp t_PythonQtNameReg(QString("libpython([0-9]).([0-9]+)\\.so$"));
foreach(QString t_line, t_lines)
{
QStringList t_sub = t_line.split(' ', Qt::SkipEmptyParts);
if (t_sub.size() != 4)
continue;
if (t_PythonQtNameReg.indexIn(t_sub[0]) == -1)
continue;
TPythonVer t_PythonVer(t_PythonQtNameReg.cap(1), t_PythonQtNameReg.cap(2));
//ç¸åçæ¬åªä¿çæåé¢çé£ä¸ª
if (t_mapVer.find(t_PythonVer) != t_mapVer.end())
continue;
t_PythonVer.path = QFileInfo(t_sub[3]).absolutePath();
t_mapVer.insert(t_PythonVer, 0);
qDebug() << "find python ver:" << t_PythonVer.MajorVersion << "." << t_PythonVer.MinorVersion;
}
ReorganizePythonVersion(_listVer, t_mapVer, m_PriorityVersion);
}
#endif
PythonQtLoader::PythonQtLoader(QObject* _parent)
:QObject(_parent)
{
g_pPythonQtLoader = this;
}
void PythonQtLoader::setPythonHome(const QString& _Dir)
{
m_PythonHome = QDir(_Dir).absolutePath();
//å¨ubuntu2204ï¼å¤§æ¦åºè¯¥è®¾ç½®è·¯å¾ä¸º/usr, éè¿import sys/nprint(sys.prefix)å¾å°
}
void PythonQtLoader::setPythonVersionPriority(const QString& _Version)
{
int t_pos = _Version.indexOf(".");
if ((t_pos) >= 0)
{
m_PriorityVersion.MajorVersion = _Version.mid(0, t_pos);
m_PriorityVersion.MinorVersion = _Version.mid(t_pos + 1);
}
else
{
m_PriorityVersion.MajorVersion = _Version.mid(0, 1);
m_PriorityVersion.MinorVersion = _Version.mid(1);
}
}
#include
bool PythonQtLoader::initPython(void)
{
QList t_PythonVers;
FindPythonVersion(t_PythonVers);
if (t_PythonVers.size() == 0)
return false;
for (QList::iterator i = t_PythonVers.begin(); i != t_PythonVers.end(); ++i)
{
QString t_szPythonQt = QString("PythonQt-Qt5-Python%1.%2").arg(i->MajorVersion).arg(i->MinorVersion);
QString t_szPythonQt_QtAll = QString("PythonQt_QtAll-Qt5-Python%1.%2").arg(i->MajorVersion).arg(i->MinorVersion);
#if defined(Q_OS_WIN)
QString t_szPython = QString("python%1%2").arg(i->MajorVersion).arg(i->MinorVersion);
#elif defined(Q_OS_LINUX)
QString t_szPython = QString("python%1.%2").arg(i->MajorVersion).arg(i->MinorVersion);//libpython3.10.soï¼ååé½å¯ä»¥ç±Qtèªå¨å ä¸
#endif
#ifndef NDEBUG
t_szPythonQt += "_d";
t_szPythonQt_QtAll += "_d";
#if defined(Q_OS_WIN)
t_szPython += "_d";
#endif
#endif
//å ä¸è·¯å¾ï¼ä¿è¯æ¯è½½å
¥æå®çé£ä¸ªï¼è䏿¯å
¶ä»çä»ä¹å°æ¹ççæ¬
QLibrary t_PythonLib(i->path + "/" + t_szPython);
qDebug() << "load " << t_szPython;
if (!t_PythonLib.load())
{
qDebug() << t_szPython << " load fail";
continue;
}
QLibrary t_PythonQtLib(t_szPythonQt);
qDebug() << "load " << t_szPythonQt;
if (!t_PythonQtLib.load())
{
qDebug() << t_szPythonQt << " load fail";
continue;
}
QLibrary t_PythonQt_QtAllLib(t_szPythonQt_QtAll);
qDebug() << "load " << t_szPythonQt_QtAll;
if (!t_PythonQt_QtAllLib.load())
{
qDebug() << t_szPythonQt_QtAll << " load fail";
continue;
}
m_pPy_SetPythonHome = (_Py_SetPythonHome)t_PythonLib.resolve("Py_SetPythonHome");
m_pPyModule_Clear = (__PyModule_Clear)t_PythonLib.resolve("_PyModule_Clear");
m_pPyConfig_InitPythonConfig = (_PyConfig_InitPythonConfig)t_PythonLib.resolve("PyConfig_InitPythonConfig");
m_pPyConfig_SetArgv = (_PyConfig_SetArgv)t_PythonLib.resolve("PyConfig_SetArgv");
m_pPy_InitializeFromConfig = (_Py_InitializeFromConfig)t_PythonLib.resolve("Py_InitializeFromConfig");
Q_ASSERT(m_pPy_SetPythonHome != NULL && m_pPyModule_Clear != NULL &&
m_pPyConfig_InitPythonConfig != NULL && m_pPyConfig_SetArgv != NULL && m_pPy_InitializeFromConfig != NULL);
#if defined(Q_OS_WIN)
m_pPy_SetPythonHome((wchar_t*)(i->path).utf16());
#elif defined(Q_OS_LINUX)
if (m_PythonHome.isEmpty())
{
QProcess t_ProcessPython;
t_ProcessPython.start(QString("python%1.%2").arg(i->MajorVersion).arg(i->MinorVersion), QStringList() << "-c" << "import sys;print(sys.prefix)");
t_ProcessPython.waitForFinished();
m_PythonHome = QString(t_ProcessPython.readAllStandardOutput());
}
m_pPy_SetPythonHome((wchar_t*)(m_PythonHome).utf16());
#endif
m_pPythonQt_init = (_PythonQt_init)t_PythonQtLib.resolve("PythonQt_init");
m_pPythonQt_self = (_PythonQt_self)t_PythonQtLib.resolve("PythonQt_self");
m_pPythonQt_CreateObjectPtr = (_PythonQt_CreateObjectPtr)t_PythonQtLib.resolve("PythonQt_CreateObjectPtr");
m_pPythonQt_QtAll_init = (_PythonQt_QtAll_init)t_PythonQt_QtAllLib.resolve("PythonQt_QtAll_init");
Q_ASSERT(m_pPythonQt_init != NULL && m_pPythonQt_self != NULL && m_pPythonQt_CreateObjectPtr != NULL && m_pPythonQt_QtAll_init != NULL);
qDebug() << "resolve PythonQt Module over ";
m_pPythonQt_init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut, QByteArray());
qDebug() << "PythonQt_init over ";
m_pPythonQt_QtAll_init();
qDebug() << "PythonQt_QtAll_init over ";
PythonQt* t_pPythonQt = m_pPythonQt_self();
qDebug() << "PythonQt_self over ";
return true;
}
return false;
}
void PythonQtLoader::loadCommonScript(const QString& _Dir)
{
PythonQt* t_pPythonQt = m_pPythonQt_self();
qDebug() << "PythonQt_self over ";
//ä¸ç¥éåªäºç±»éè¦æ¾å¼æ³¨åï¼å ä¸ºå¤§å¤æ°ç±»ä¼¼ä¹å¯ä»¥èªå¨æ³¨åï¼æ¯å¦GtManageä¸çé£äºåçªå£
t_pPythonQt->registerClass(&QT_ClientCtrl::staticMetaObject, "GtManage");
t_pPythonQt->registerClass(&QT_ServerModel::staticMetaObject, "GtManage");
t_pPythonQt->registerClass(&TRunProcess::staticMetaObject, "GtManage");
t_pPythonQt->registerCPPClass("QProcessSet", "", "GtManage", PythonQtCreateObject);
//t_pPythonQt->registerCPPClass("TRunProcess", "", "GtManage", PythonQtCreateObject);
t_pPythonQt->registerCPPClass("PROTO_MANAGERTOOL", "", "GtManage", PythonQtCreateObject);
qDebug() << "registerClass over ";
PythonQtObjectPtr* t_pPythonMainModule = m_pPythonQt_CreateObjectPtr(t_pPythonQt->getMainModule());
Q_ASSERT(!t_pPythonMainModule->isNull());
t_pPythonMainModule->addObject("g_GtManage", g_pManage);
t_pPythonMainModule->addObject("g_App", g_app);
QStringList t_Files = QDir(_Dir).entryList(QStringList() << "*.py", QDir::Files);
foreach(QString t_File, t_Files)
{
t_pPythonMainModule->evalFile(_Dir + t_File);
}
delete t_pPythonMainModule;
}
void PythonQtLoader::loadExtraScript(const QString& _Dir)
{
QStringList t_Files = QDir(_Dir).entryList(QStringList() << "*.py", QDir::Files);
foreach(QString t_File, t_Files)
{
PyConfig t_PyConfig;
m_pPyConfig_InitPythonConfig(&t_PyConfig);
QString t_ScriptPath = _Dir + t_File;
wchar_t* const t_PyArgv[] = { const_cast(L""), (wchar_t*)(t_ScriptPath.utf16()) };
int t_PyArgc = _countof(t_PyArgv);
PyStatus t_status = m_pPyConfig_SetArgv(&t_PyConfig, t_PyArgc, t_PyArgv);
if (t_status._type == PyStatus::_PyStatus_TYPE_OK)
m_pPy_InitializeFromConfig(&t_PyConfig);
QString t_ModuleName = QFileInfo(t_File).baseName();
PythonQtObjectPtr* t_Module = m_pPythonQt_CreateObjectPtr(m_pPythonQt_self()->createModuleFromScript(t_ModuleName));
t_Module->addObject("g_GtManage", g_pManage);
t_Module->addVariable("__file__", t_ScriptPath);
t_Module->evalFile(t_ScriptPath);
t_Module->call("main", QVariantList() << true);
delete t_Module;
}
}
void PythonQtLoader::loadMudule(const QString& _ModuleName, const QString& _Path)
{
PythonQtObjectPtr* t_Module = m_pPythonQt_CreateObjectPtr(m_pPythonQt_self()->getModule(_ModuleName));
if (t_Module->isNull())
{
t_Module = m_pPythonQt_CreateObjectPtr(m_pPythonQt_self()->createModuleFromScript(_ModuleName));
t_Module->addObject("g_GtManage", g_pManage);
t_Module->addVariable("__file__", _Path);
t_Module->evalFile(_Path);
t_Module->call("main", QVariantList() << true);
}
delete t_Module;
}
void PythonQtLoader::unloadMudule(const QString& _ModuleName)
{
PythonQtObjectPtr* t_Module = m_pPythonQt_CreateObjectPtr(m_pPythonQt_self()->getModule(_ModuleName));
if (!t_Module->isNull())
{
t_Module->call("main", QVariantList() << false);
//éæ¾æ¨¡ååè½
m_pPyModule_Clear(*t_Module);
//仿¨¡åå表éå é¤
m_pPythonQt_self()->removeModule(_ModuleName);
}
delete t_Module;
}
PythonQtLoader::~PythonQtLoader()
{
}