查看模块调试问题, 在debug模式下面,使用python312_d.lib,会有调用pyd失败问题,原因是debug release不兼容

This commit is contained in:
DESKTOP-450PEFP\mainc 2026-04-01 17:13:40 +08:00
parent 6e314845ed
commit f1e8200b4e
14 changed files with 1241 additions and 45 deletions

View File

@ -0,0 +1,81 @@
#include "PluginDialog.h"
#include <QLabel>
#include <QDoubleValidator>
#include <QMessageBox>
#define DT_LEFT Qt::AlignLeft
#define DT_TOP Qt::AlignTop
#pragma execution_character_set("utf-8")
CPluginDialog::CPluginDialog(QWidget* parent):QDialog(parent)
, mNARMS(250)
{
//pushButton
uiDlg = new Ui_PluginDialog();
uiDlg->setupUi(this);
// 初始化按钮
initActions();
}
CPluginDialog::~CPluginDialog()
{
}
void CPluginDialog::paintEvent( QPaintEvent * event )
{
}
void CPluginDialog::init()
{
}
void CPluginDialog::initActions()
{
QAction* pAct1 = new QAction("Act1"); // 按钮1
pAct1->setProperty("icon_v", "icon/11.png"); // 设置按钮icon属性
pAct1->setToolTip("PluginDialog按钮1Tip"); // 设置按钮Tip
//
connect(pAct1, &QAction::triggered, this, &CPluginDialog::onAction1Func);
QAction* pAct2 = new QAction("Act2");
pAct2->setProperty("icon_v", "icon/bin.png");
pAct2->setToolTip("PluginDialog按钮2Tip");
connect(pAct2, &QAction::triggered, this, &CPluginDialog::onAction2Func);
QAction* pAct3 = new QAction("Act3");
pAct3->setProperty("icon_v", "icon/black.png");
pAct3->setToolTip("PluginDialog按钮2Tip111");
connect(pAct3, &QAction::triggered, this, &CPluginDialog::onAction3Func);
QAction* pAct4 = new QAction("Act4");
pAct4->setProperty("icon_v", "icon/black.png");
pAct4->setToolTip("PluginDialog按钮4Tip111");
m_listAction << pAct1;
m_listAction << pAct2;
m_listAction << pAct3;
m_listAction << pAct4;
}
QList<QAction *> CPluginDialog::getListAction()
{
return m_listAction;
}
void CPluginDialog::onAction1Func()
{
QMessageBox::information(NULL, "提示", "example_plugin 我是按钮111111弹窗");
}
void CPluginDialog::onAction2Func()
{
QMessageBox::information(NULL, "提示", "example_plugin 我是按钮222222弹窗");
}
void CPluginDialog::onAction3Func()
{
QMessageBox::information(NULL, "提示", "example_plugin 我是按钮333333弹窗");
}

View File

@ -0,0 +1,47 @@
#ifndef PLUGIN_DIALOG
#define PLUGIN_DIALOG
#include <QDialog>
#include <QWidget>
#include "ui_PluginDialog.h"
#define BOOL bool
#pragma once
#include <QAction>
class CPluginDialog:public QDialog
{
Q_OBJECT
protected:
void paintEvent( QPaintEvent * event );
public:
CPluginDialog(QWidget* parent);
~CPluginDialog();
void init();
// 初始化按钮显示在平台右侧ToolBar
void initActions();
// 平台获取该模块中自定义的QAction
QList<QAction*> getListAction();
public:
float m_StartDep;
float m_EndDep;
int mNARMS;
private:
Ui_PluginDialog *uiDlg;
QList<QAction*> m_listAction;
public:
public slots:
// QAction的槽函数处理
void onAction1Func();
void onAction2Func();
void onAction3Func();
};
#endif

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PluginDialog</class>
<widget class="QDialog" name="PluginDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>425</width>
<height>304</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>160</x>
<y>120</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>TEST</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>170</x>
<y>160</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,350 @@
#include "memrdwt.h"
#include "math.h"
#include "basefun.h"
#include "DepthProgress.h"
#include "PluginDialog.h"
#include "pythonhandler.h"
Slf_WAVE mWave[1];
extern "C"{
__declspec (dllexport) struct INC_STRU INC=INC={6,
"FWGN_W:波名1,raw;;\
NWGN_W:2,raw;;\
RWGN_W:3,raw;;\
GR:,API;;\
NWGN_C:线2,raw;;\
RWGN_C:线3,raw;;\
"
};//输入曲线定义 6:输入6条数据, "数据英文:数据中文,数据单位;;"
__declspec (dllexport) struct INP_STRU INP; //使用GetINValue(RGN_C, 6, 1);函数需要定义该变量
__declspec (dllexport) struct OUTC_STRU OUTC={2,
"ATT:波名1,raw;;\
THCAV:线1,raw;;\
"
};//输出曲线定义 2:输出2条数据, "数据英文:数据中文,数据单位;;"(注:先写波形数据,再写曲线数据)
__declspec (dllexport) struct OUTP_STRU OUTP;
__declspec (dllexport) struct HD_STRU HD={0.0,9999.0,0.0,0.0,0.0,0.0,0.0,"example_plugin.INP","example_plugin.TLP"};
__declspec (dllexport) struct CONC_STRU CONC={4,
"CTH:参数名1,mm;;;;10.5;\
CT:2,%;;;;1;\
IT:3,mm;;;;9.7;\
MT:4,%;;;;1;"
};//常量参数定义 4:4个参数, "数据英文:数据中文,单位;;;;参数默认值;"
__declspec (dllexport) struct CON_STRU CON={10.5, 1, 9.7, 1}; //再次设置默认值(需要与前面相同)
__declspec (dllexport) struct ErrorInf errorinf;
//定义输出数据类型(注:需要与前面输出定义一一对应)
__declspec (dllexport) struct LogType LogType={WAVE_OBJECT, CURVE_OBJECT}; //{WAVE_OBJECT, CURVE_OBJECT}
__declspec( dllexport ) CMemRdWt MemRdWt;
__declspec (dllexport) int example_plugin(); //改成自己的工程名
//以下两行代码用于创建自定义界面来控制参数的对话框如果不需开发者自己定义对话框则不需要这两行及下面的InitDialog函数初始化
__declspec (dllexport) QDialog* InitDialog(QWidget *pF);
__declspec( dllexport ) CPluginDialog *PLGDialog=NULL;
__declspec( dllexport ) void* getAction_CApi(int* count);
__declspec (dllexport) int Init();
__declspec (dllexport) int Finish();
}
struct Process_Struct{
float fa;
float fb;
float fc;
int Process();
};
int Init()
{
return 1;
}
//此部分用于创建对话框,该第一话框将被显示在平台的参数区
//如果需要独立显示对话框,则不需熬此函数
QDialog* InitDialog(QWidget *pF)
{
PLGDialog=new CPluginDialog(pF);
return PLGDialog;
}
// 实现
void* getAction_CApi(int* count)
{
if(PLGDialog == nullptr)
InitDialog(nullptr);
QList<QAction*> actions = PLGDialog->getListAction();
int ncnt = actions.size();
*count = ncnt;
// 需要确保内存管理方式一致
QAction** array = new QAction*[ncnt];
for(int i = 0; i < ncnt; ++i) {
array[i] = actions[i];
}
return array;
}
int Finish()
{
return 1;
}
int example_plugin()
{
Process_Struct Process;
return Process.Process();
}
//固井结构体(注:此处为表格输出示例)
typedef struct ss_struct
{
int GNO;
float GSDEP,GEDEP;
int GRESULT;
} GUJING;
//结论结构体
void callPython(float FGN_C, float NGN_C, float RGN_C, float* FGN_W, float* NGN_W, float* Att0all, int nlen)
{
QVariantList args;
QVariantList arg1;
QVariantList arg2;
// 填充列表
for (int i = 0; i < nlen; ++i) {
arg1 << (double)FGN_W[i];
arg2 << (double)NGN_W[i];
}
args.append(QVariant::fromValue(arg1)); // 直接将 innerList1 作为元素添加
args.append(QVariant::fromValue(arg2)); // 使用 << 操作符
args << (double)FGN_C << (double)NGN_C << (double)RGN_C;
PythonHandler::getInstance()->executeScript("fdsa4_test", "process_arrays", args, Att0all, nlen);
}
int Process_Struct::Process()
{
if(HD.Sdep >= HD.EndDep)
{
// AfxMessageBox("当前处理井段深度有误!\n已停止计算");
// AfxMessageBox("The current depth of the processing interval is incorrect!\n Calculation has been stopped");
return 0;
}
/*******************************************************写数据前的准备操作*******************************************************
******************************begin****************************/
//1初始化参数、输入
MemRdWt.Const();
MemRdWt.In();
//2波形类型的输出数据初始化检查
char outname[2][16];
int OUTindex = 0, WaveIndex = 0;
MemRdWt.GetOutCurveName(OUTindex, outname[OUTindex]);//获取输出数据名称参数1是序列值从0开始波形/曲线均使用GetOutCurveName函数
int index1 = MemRdWt.OpenWave(outname[OUTindex]);//检查是否存在outname[OUTindex]波形
if(index1 < 0) //返回索引小于0说明没有该波形需要创建
{
//创建方式:
Slf_WAVE myWave;
strcpy(myWave.Name, outname[OUTindex]);
strcpy(myWave.AliasName, outname[OUTindex]);
strcpy(myWave.DepthUnit, "m");
myWave.CodeLen = 4;
myWave.RepCode = 4;
myWave.DefVal = 0;
myWave.StartDepth = HD.Sdep;
myWave.EndDepth = HD.Edep;
myWave.DepLevel = HD.Rlev;
strcpy(myWave.DepthUnit, "m");
myWave.StartTime = 0; //起始记录时间
myWave.TimeLevel = 5; //时间采样间隔
myWave.ArrayNum = 1; //阵列数
myWave.TimeSamples = 36; //时间采样总数
strcpy(myWave.TimeUnit, "ns"); //时间单位
index1 = MemRdWt.OpenWave((Slf_WAVE *)&myWave); //创建波形(注:此时返回索引应>1代表创建成功
}
if(index1 < 0)
{
// AfxMessageBox("阵列数据创建失败!\n已停止计算");
// AfxMessageBox("Array data creation failed!\nCalculation stopped");
return 0;
}else{
WaveIndex = index1;
}
//3曲线类型的输出数据初始化检查
OUTindex = 1;//按extern "C"中定义的输出数据顺序设置
MemRdWt.GetOutCurveName(OUTindex, outname[OUTindex]);//获取输出数据名称参数1是序列值从0开始
index1 = MemRdWt.OpenCurve(outname[1]);//index1 = MemRdWt.OpenCurve("EEE");//检查数据是否存在//outname[OUTindex]
if(index1 < 0) //返回索引小于0说明没有这条曲线需要创建
{
//创建方式:
Slf_CURVE myCurve; //定义曲线对象
strcpy(myCurve.Name, outname[1]); //设置名称
strcpy(myCurve.AliasName, outname[1]); //设置别名
strcpy(myCurve.Unit, "m"); //设置数据单位
myCurve.CodeLen = 4; //设置字节长度4float
myCurve.RepCode = 4; //设置数据类型4float
myCurve.DefVal = 0; //设置默认值
myCurve.StartDepth = HD.Sdep; //设置起始深度
myCurve.EndDepth = HD.Edep; //设置结束深度
myCurve.DepLevel = HD.Rlev; //设置采样间隔
strcpy(myCurve.DepthUnit, "m"); //设置深度单位
index1 = MemRdWt.OpenCurve((Slf_CURVE *)&myCurve); //创建曲线(注:此时返回索引应>1代表创建成功
}
if(index1 < 0)
{
// AfxMessageBox("波形数据创建失败!\n已停止计算");
// AfxMessageBox("Array data creation failed!\nCalculation stopped");
return 0;
}
/*********************************************************end************************************************************/
//4平台进度条设置
DepthProgress mmProgress;
mmProgress.CreatProgress(HD.Stdep, HD.EndDep, "程序处理中...");
//5深度循环
while(HD.Dep <= HD.EndDep)//逐深度处理
{
mmProgress.SetDepth(HD.Dep);//设置平台进度条
/********************************************************获取常量参数示例***************************************************
******************************begin****************************/
//GetPosValue函数的参数3为序列值要和extern "C"的CONC内容对应上从1开始
float CTH, CT, IT, MT;
GetPosValue(CTH, CON, 1, 1);
GetPosValue(CT, CON, 2, 1);
GetPosValue(IT, CON, 3, 1);
GetPosValue(MT, CON, 4, 1);
/***************************************************************end*************************************************************/
/********************************************************读数据示例***************************************************************
*****************************begin****************************/
//1读wave数据
char inname[3][36];
int index[4] = {-1};
//获取输入数据对应的波列名称参数1是序列值从0开始
MemRdWt.GetInCurveName(0, inname[0]);
MemRdWt.GetInCurveName(1, inname[1]);
MemRdWt.GetInCurveName(2, inname[2]);
//获取波列数据对应的index,再读数据
index[0] = MemRdWt.OpenWave(inname[0]);
index[1] = MemRdWt.OpenWave(inname[1]);
index[2] = MemRdWt.OpenWave(inname[2]);
if(index[0] < 0 || index[1] < 0 || index[2] < 0){
// AfxMessageBox("波列数据获取失败\n已停止计算");
// AfxMessageBox("Waveform data acquisition failed\nCalculation stopped");
return 0;
}
float FGN_W[60], NGN_W[60], RGN_W[60]; //必须根据wave数据的大小声明
int a = 0;
int b = 0; int c = 0;
c = MemRdWt.ReadWaveToFloatBuf(index[2], HD.Dep, 1, RGN_W);
b = MemRdWt.ReadWaveToFloatBuf(index[1], HD.Dep, 1, NGN_W);
a = MemRdWt.ReadWaveToFloatBuf(index[0], HD.Dep, 1, FGN_W);//读取wave数据从HD.Dep深度开始读1个深度位置的wave数据至FGN_W中
//2读曲线数据
//GetINValue函数的参数2为序列值要和extern "C"的INC内容的顺序对应上
float FGN_C, NGN_C, RGN_C;
GetINValue(FGN_C, 4, 1);
GetINValue(NGN_C, 5, 1);
GetINValue(RGN_C, 6, 1);
/********************************************************end*************************************************************/
/*******************************************处理程序示例(注:改成自己的算法)******************************************
*****************************begin****************************/
float Att0all[36];
float THCAV = 0.0;
bool bPython = true;
if (bPython)
{
callPython(FGN_C, NGN_C, RGN_C, FGN_W, NGN_W, Att0all, 36);
}
else
{
for(int i = 0; i < 36; i++)
Att0all[i] = FGN_W[i] + NGN_W[i];
THCAV = FGN_C + NGN_C + RGN_C;
}
/********************************************************end********************************************************/
/*******************************************************向平台写数据示例**********************************************
*****************************begin****************************/
//1写wave数据
MemRdWt.WriteWave(WaveIndex, HD.Dep, 1, &Att0all);
//2写curve数据
int THCAV_index = MemRdWt.OpenCurve(outname[1]);//outname[1]
if(THCAV_index > 0)
MemRdWt.WriteCurve(THCAV_index, HD.Dep, 1, &THCAV);
/*******************************************************end**********************************************************/
MemRdWt.In(); //继续深度循环
}
/*************************************************向平台写表格示例*************************************************************
*****************************begin****************************/
//1固井结论表格
int itable1 = MemRdWt.OpenOG_RESULT("固井质量");//例如表格取名为“固井质量”
MemRdWt.SetTableRecordCount(itable1, 0); //清空原有表格数据
GUJING *CCNN2 = new GUJING[5];
for(int i = 0; i < 5; i++)
{
CCNN2[i].GNO = i + 1;
CCNN2[i].GSDEP = 2000 + i * 10;
CCNN2[i].GEDEP = 2000 + (i + 1) * 10;
CCNN2[i].GRESULT = 1;
int temp = MemRdWt.WriteTable(itable1, i + 1, &CCNN2[i]);
}
//2其他表格
struct Slf_RST{
int Order;
float Depth;
float CorrDepth;
};
struct Slf_RST m_Result;
itable1 = MemRdWt.OpenTable("ABCD");
if (itable1 < 0)
{
itable1 = MemRdWt.Open_Set_Table("ABCD",0,3,
"NO,DEPTH,DDEP",
"4,4,4",//字段长度
"1,4,4",//字段类型
"0,0,0");//字段备注,1-枚举
}
MemRdWt.SetTableRecordCount(itable1,3); //设置表格有3行数据
for(int j = 0; j < 3; j++)
{
memset(&m_Result, 0, sizeof(Slf_RST));
m_Result.Order = j + 1;
m_Result.Depth = 10;
m_Result.CorrDepth = 20 + j;
MemRdWt.WriteTable(itable1, j + 1, &m_Result);
}
MemRdWt.CloseTable(itable1);
/******************************************************end*************************************************************/
return 1;
}

View File

@ -0,0 +1,32 @@
#pragma once
#define BOOL bool
#if defined(_WIN64)
typedef __int64 INT_PTR, *PINT_PTR;
typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
typedef __int64 LONG_PTR, *PLONG_PTR;
typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
#define __int3264 __int64
#else
typedef _W64 int INT_PTR, *PINT_PTR;
typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
typedef _W64 long LONG_PTR, *PLONG_PTR;
typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
#define __int3264 __int32
#endif
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
typedef long LONG;
#define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8))
#define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))
#define LOWORD(l) ((WORD)(((DWORD_PTR)(l)) & 0xffff))
#define HIWORD(l) ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))
#define LOBYTE(w) ((BYTE)(((DWORD_PTR)(w)) & 0xff))
#define HIBYTE(w) ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff))
#include "DepthProgress.h"

View File

@ -0,0 +1,54 @@
TEMPLATE = lib
TARGET = example_plugin
DEFINES += _TIMESPEC_DEFINED
QT += core \
gui \
network \
opengl
INCLUDEPATH += $$PWD/../../common \
$$PWD/../../include \
$$PWD/../../Slfio/include \
$$PWD/../../BaseFun/include \
$$PWD/../../Bin/Python312/include\
$$PWD/../../Bin/Python312/Lib/site-packages/numpy/_core/include\
$(QTDIR)/include \
OBJECTS_DIR = ../obj
CONFIG(debug, debug|release){
DESTDIR = $$PWD/../../Bin/app
TARGET = $$join(TARGET,,,d) #为debug版本生成的文件增加d的后缀
} else {
DESTDIR = $$PWD/../../BinR/app
TARGET = $$join(TARGET,,,)
}
CONFIG += qt warn_off \
debug_and_release
DEFINES += QT_DLL
HeadS += ../include/*.h
SOURCES += *.cpp
HEADERS += *.h
# 设置源文件编码为UTF-8
#win32: QMAKE_CXXFLAGS += /source-charset:utf-8 /execution-charset:utf-8
#macx: QMAKE_CXXFLAGS += -finput-charset=UTF-8 -fexec-charset=UTF-8
#linux: QMAKE_CXXFLAGS += -finput-charset=UTF-8 -fexec-charset=UTF-8
#CPATH = $$system(pwd)
# 目标文件夹
#CATEGORY = OSGDataModel
CONFIG(debug, debug|release){
LIBS += -L$$PWD/../../Bin -lBaseFund -lslfiod
LIBS += -L$$PWD/../../Bin/Python312/libs -lpython312
} else {
LIBS += -L$$PWD/../../BinR -lBaseFun -lslfio
LIBS += -L$$PWD/../../Bin/Python312/libs -lpython312
}
FORMS += \
PluginDialog.ui

View File

@ -0,0 +1,436 @@
#include "pythonhandler.h"
#include <QCoreApplication>
#include <QFile>
#include <QProcessEnvironment>
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<QString, QVariant> 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<QString, QVariant> 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();
}
}

View File

@ -0,0 +1,59 @@
#ifndef PYTHONHANDLER_H
#define PYTHONHANDLER_H
#include <QObject>
#include <QString>
#include <QVariant>
#include <QDebug>
// 在包含 Python.h 之前,保存并取消 Qt 的 slots 宏
#pragma push_macro("slots")
#undef slots
#include <Python.h>
#include <numpy/arrayobject.h>
// 包含之后恢复 slots 宏(如果需要继续使用 Qt 的 slots
#pragma pop_macro("slots")
#define PYTHON_VER "Python312"
class PythonHandler : public QObject
{
Q_OBJECT
public:
explicit PythonHandler(QObject *parent = nullptr);
~PythonHandler();
static PythonHandler* getInstance();
// 初始化Python解释器
bool initialize();
void setupEnvironment(QString strPy);
QString capturePythonError();
// 执行Python脚本
QVariant executeScript(const QString &scriptPath,
const QString &functionName,
const QVariantList &args = QVariantList() ,
float* outAtt0all = NULL, int nlen = 0);
// 直接执行Python代码
QVariant executeCode(const QString &code);
// 关闭Python解释器
void finalize();
signals:
void addLog(QString msg);
private:
bool m_initialized;
QVariant pythonObjectToQVariant(PyObject *obj);
PyObject* qVariantToPythonObject(const QVariant &value);
};
#endif // PYTHONHANDLER_H

View File

@ -46,7 +46,7 @@ HEADERS += \
CONFIG(debug, debug|release){
LIBS += -L$$PWD/../../Bin -lslfiod
LIBS += -L$$PWD/../../Bin -lBaseFund
LIBS += -LD:/Python312/libs -lpython312_d
LIBS += -LD:/Python312/libs -lpython312
# LIBS += -L$(QTDIR)/lib -lQtNetworkd4
# LIBS += -LD:/Qt4.7.1/lib -lQtNetworkd4
} else {

View File

@ -1,12 +0,0 @@
# This Python file uses the following encoding: utf-8
# if __name__ == "__main__":
# pass
import os
import sys
import numpy as np
def process_arrays(a, b, c, d, e):
result = [x + y for x, y in zip(a, b)]
return np.array(result), c+d+e

View File

@ -7,10 +7,6 @@ PythonHandler::PythonHandler(QObject *parent)
: QObject(parent)
, m_initialized(false)
{
// 初始化Python
if (!this->initialize()) {
qDebug() << "Python初始化失败";
}
}
PythonHandler::~PythonHandler()
@ -30,8 +26,11 @@ bool PythonHandler::initialize()
return true;
}
setupEnvironment();
// 获取程序所在目录
QString appDir = QCoreApplication::applicationDirPath();
QString strPy= appDir + "/" + PYTHON_VER;
setupEnvironment(strPy);
strPy.toStdWString().c_str();
// 初始化Python解释器
Py_Initialize();
@ -44,22 +43,15 @@ bool PythonHandler::initialize()
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";
// 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"
"print('Python_:', sys.path)\n"
"sys.path.append('%1')\n"
"sys.path.append('%2')\n"
"sys.path.append('%3')\n"
"sys.path.append('%4')\n"
"sys.path.append('%5')\n"
"sys.path.append('%6')\n"
"print('end_:', sys.path)\n"
"print('========== Python 调试信息 ==========')\n"
"print('当前工作目录:', os.getcwd())\n"
"print('exepath:', sys.executable)\n"
@ -67,8 +59,7 @@ bool PythonHandler::initialize()
"for p in sys.path:\n"
" print(' -', p)\n"
"print('======================================')\n"
).arg(currentPath).arg(scriptPath)
.arg(strPy).arg(scriptPython2).arg(scriptPython3).arg(scriptPython4);
).arg(scriptPath);
// emit addLog(pythonCode);
PyRun_SimpleString(pythonCode.toStdString().c_str());
@ -76,28 +67,24 @@ bool PythonHandler::initialize()
return true;
}
void PythonHandler::setupEnvironment()
void PythonHandler::setupEnvironment(QString strPy)
{
// 获取程序所在目录
QString appDir = QCoreApplication::applicationDirPath();
// 使用 Qt 的方式设置环境变量
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
// 设置 PYTHONHOME
qputenv("PYTHONHOME", appDir.toLocal8Bit());
qputenv("PYTHONHOME", strPy.toLocal8Bit());
QString strPy= appDir + "/" + PYTHON_VER;
// 设置 PYTHONPATH
QString pythonPath = strPy + "/Lib;" + strPy + "/DLLs;" + strPy + "/python_scripts";
QString pythonPath = strPy + "/Lib;" + strPy + "/lib/site-packages;" + strPy + "/DLLs;";
qputenv("PYTHONPATH", pythonPath.toLocal8Bit());
// 修改 PATH添加程序目录
QString currentPath = QString::fromLocal8Bit(qgetenv("PATH"));
QString newPath = appDir + ";" + strPy + "/DLLs;" + currentPath;
QString newPath = strPy + "/DLLs;" + currentPath;
qputenv("PATH", newPath.toLocal8Bit());
qDebug() << "环境变量已设置:";
qDebug() << "Environment:";
qDebug() << "PYTHONHOME:" << qgetenv("PYTHONHOME");
qDebug() << "PYTHONPATH:" << qgetenv("PYTHONPATH");
}
@ -225,6 +212,32 @@ QVariant PythonHandler::pythonObjectToQVariant(PyObject *obj)
}
}
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));
#ifdef _RELEASE
Py_DECREF(pstr);
#endif
}
}
#ifdef _RELEASE
// 清理
Py_XDECREF(ptype);
Py_XDECREF(pvalue);
Py_XDECREF(ptraceback);
#endif
return errorMsg;
}
QVariant PythonHandler::executeScript(const QString &scriptPath,
const QString &functionName,
const QVariantList &args,
@ -247,11 +260,22 @@ QVariant PythonHandler::executeScript(const QString &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) {
PyErr_Print();
QString error = capturePythonError();
qDebug() << "Python error:" << error;
//PyErr_Print();
emit addLog("无法导入Python模块:" + moduleName);
return QVariant();
}
@ -319,6 +343,78 @@ QVariant PythonHandler::executeScript(const QString &scriptPath,
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<QString, QVariant> 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()) {

View File

@ -31,7 +31,9 @@ public:
// 初始化Python解释器
bool initialize();
void setupEnvironment();
void setupEnvironment(QString strPy);
QString capturePythonError();
// 执行Python脚本
QVariant executeScript(const QString &scriptPath,

View File

@ -95,6 +95,12 @@ typedef struct s2_struct
void callPython(float FGN_C, float NGN_C, float RGN_C, float* FGN_W, float* NGN_W, float* Att0all, int nlen)
{
QVariantList args;
// args << 0.77;
// args << 2.93;
// args << 50;
// PythonHandler::getInstance()->executeScript("UCS_test_0330", "get_UCS_Horsrud_correlation_shale", args, NULL, nlen);
// return;
QVariantList arg1;
QVariantList arg2;
// 填充列表

View File

@ -4,7 +4,7 @@ import numpy as np
setup(
ext_modules=cythonize(
"fdsa4_test.py", # 要编译的Python文件
"UCS_test_0330.py", # 要编译的Python文件
compiler_directives={
'language_level': 3, # Python 3
'boundscheck': False, # 关闭边界检查提升性能