基于 Qt5.10.1 调用 Python 脚本实现简单的四则运算

https://github.com/mygit03/TestPython.git

Qt调用JS脚本

 

首先建立一个工程;

导入Python库;

新建 Python 脚本

TestPython.pro

#-------------------------------------------------
#
# Project created by QtCreator 2018-12-25T15:29:45
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = TestPython
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += \
        main.cpp \
        widget.cpp

HEADERS += \
        widget.h

unix|win32: LIBS += -LC:/Python27/libs/ -lpython27

INCLUDEPATH += C:/Python27/include
DEPENDPATH += C:/Python27/include

DISTFILES += \
    pytest.py

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QDoubleSpinBox>
#include <QPushButton>

#include <Python.h>

enum{
    Method_sum = 0,
    Method_sub = 1,
    Method_mul = 2,
    Method_div = 3,
    Method_mod = 4,
};

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

    void init();

    void CallPython(const QString file);

    void CalulateMethod(const char * method, int type = Method_sum);

private slots:
    void choosePythonFile();

    void calculate();

private:
    QLabel          *m_pFileLabel;
    QLineEdit       *m_pFileLE;
    QPushButton     *m_pFileBtn;

    QLabel          *m_pALabel;
    QDoubleSpinBox  *m_pADoubleSpinBox;
    QLabel          *m_pBLabel;
    QDoubleSpinBox  *m_pBDoubleSpinBox;
    QPushButton     *m_pCalculateBtn;

    QLabel          *m_pSumLabel;
    QLineEdit       *m_pSumLE;
    QLabel          *m_pSubLabel;
    QLineEdit       *m_pSubLE;
    QLabel          *m_pMulLabel;
    QLineEdit       *m_pMulLE;
    QLabel          *m_pDivLabel;
    QLineEdit       *m_pDivLE;
    QLabel          *m_pModLabel;
    QLineEdit       *m_pModLE;

    PyObject        *m_pModule;
    PyObject        *m_pArgs;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"

#include <QGridLayout>
#include <QFileDialog>
//#include <Python.h>
#include <iostream>

using namespace std;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle(tr("调用Python脚本实现简单的四则运算"));
    init();
}

Widget::~Widget()
{
}

void Widget::init()
{
    QGridLayout *gridLayout = new QGridLayout(this);
    m_pFileLabel = new QLabel(tr("Python File:"), this);
    gridLayout->addWidget(m_pFileLabel, 0, 0, 1, 1);

    m_pFileLE = new QLineEdit(this);
    m_pFileLE->setReadOnly(true);
    gridLayout->addWidget(m_pFileLE, 0, 1, 1, 5);

    m_pFileBtn = new QPushButton(tr("选择"), this);
    connect(m_pFileBtn, SIGNAL(clicked(bool)), this, SLOT(choosePythonFile()));
    gridLayout->addWidget(m_pFileBtn, 0, 6, 1, 1);

    m_pALabel = new QLabel(tr("参数a:"), this);
    m_pALabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    gridLayout->addWidget(m_pALabel, 1, 0, 1, 1);

    m_pADoubleSpinBox = new QDoubleSpinBox(this);
    m_pADoubleSpinBox->setToolTip(tr("参数a"));
    gridLayout->addWidget(m_pADoubleSpinBox, 1, 1, 1, 1);

    m_pBLabel = new QLabel(tr("参数b:"), this);
    m_pBLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    gridLayout->addWidget(m_pBLabel, 1, 2, 1, 1);

    m_pBDoubleSpinBox = new QDoubleSpinBox(this);
    m_pBDoubleSpinBox->setToolTip(tr("参数b"));
    gridLayout->addWidget(m_pBDoubleSpinBox, 1, 3, 1, 1);

    m_pCalculateBtn = new QPushButton(tr("计算"), this);
    connect(m_pCalculateBtn, SIGNAL(clicked(bool)), this, SLOT(calculate()));
    gridLayout->addWidget(m_pCalculateBtn, 1, 6, 1, 1);

    m_pSumLabel = new QLabel(tr("Sum:"), this);
    m_pSumLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    gridLayout->addWidget(m_pSumLabel, 2, 0, 1, 1);

    m_pSumLE = new QLineEdit(this);
    m_pSumLE->setReadOnly(true);
    gridLayout->addWidget(m_pSumLE, 2, 1, 1, 1);

    m_pSubLabel = new QLabel(tr("Sub:"), this);
    m_pSubLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    gridLayout->addWidget(m_pSubLabel, 2, 2, 1, 1);

    m_pSubLE = new QLineEdit(this);
    m_pSubLE->setReadOnly(true);
    gridLayout->addWidget(m_pSubLE, 2, 3, 1, 1);

    m_pMulLabel = new QLabel(tr("Mul:"), this);
    m_pMulLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    gridLayout->addWidget(m_pMulLabel, 2, 4, 1, 1);

    m_pMulLE = new QLineEdit(this);
    m_pMulLE->setReadOnly(true);
    gridLayout->addWidget(m_pMulLE, 2, 5, 1, 1);

    m_pDivLabel = new QLabel(tr("Div:"), this);
    m_pDivLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    gridLayout->addWidget(m_pDivLabel, 3, 0, 1, 1);

    m_pDivLE = new QLineEdit(this);
    m_pDivLE->setReadOnly(true);
    gridLayout->addWidget(m_pDivLE, 3, 1, 1, 1);

    m_pModLabel = new QLabel(tr("Mod:"), this);
    m_pModLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    gridLayout->addWidget(m_pModLabel, 3, 2, 1, 1);

    m_pModLE = new QLineEdit(this);
    m_pModLE->setReadOnly(true);
    gridLayout->addWidget(m_pModLE, 3, 3, 1, 1);
}

void Widget::CallPython(const QString file)
{
    Py_Initialize();    // 初始化

    string chdir_cmd;
    // 将Python工作路径切换到待调用模块所在目录,一定要保证路径名的正确性
    string path = "E:/Qt/TestPython";
    if (!file.isEmpty())
    {
        path = QFileInfo(file).absolutePath().toStdString();
    }
    chdir_cmd = string("sys.path.append(\"") + path + "\")";
    const char* cstr_cmd = chdir_cmd.c_str();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString(cstr_cmd);

    // 加载模块
    PyObject* moduleName = PyString_FromString("pytest"); //模块名,不是文件名(文件名不加后缀)
    PyObject* pModule = PyImport_Import(moduleName);
    if (!pModule) // 加载模块失败
    {
        cout << "[ERROR] Python get module failed." << endl;
        return;
    }
    cout << "[INFO] Python get module succeed." << endl;

    // 设置参数
    double a = m_pADoubleSpinBox->value();
    double b = m_pBDoubleSpinBox->value();

    PyObject* args = PyTuple_New(2);        // 2个参数
    PyObject* arg1 = PyInt_FromLong(a);     // 参数一设为4
    PyObject* arg2 = PyInt_FromLong(b);     // 参数二设为3
    PyTuple_SetItem(args, 0, arg1);
    PyTuple_SetItem(args, 1, arg2);

#if 0
    // 加载函数
    PyObject* pv = PyObject_GetAttrString(pModule, "sum");
    if (!pv || !PyCallable_Check(pv))  // 验证是否加载成功
    {
        cout << "[ERROR] Can't find funftion (sum)" << endl;
        return;
    }
    cout << "[INFO] Get function (add) succeed." << endl;

    // 调用函数
    PyObject* pRet = PyObject_CallObject(pv, args);

    // 获取结果
    if (pRet)  // 验证是否调用成功
    {
        long result = PyInt_AsLong(pRet);
    }
#endif

    m_pModule = pModule;
    m_pArgs = args;

    CalulateMethod("sum", Method_sum);
    CalulateMethod("sub", Method_sub);
    CalulateMethod("mul", Method_mul);
    CalulateMethod("div", Method_div);
    CalulateMethod("mod", Method_mod);

    Py_Finalize();
}

void Widget::CalulateMethod(const char *method, int type)
{
    // 加载函数
    PyObject* pv = PyObject_GetAttrString(m_pModule, method);
    if (!pv || !PyCallable_Check(pv))  // 验证是否加载成功
    {
        cout << "[ERROR] Can't find funftion (sum)" << endl;
        return;
    }
    cout << "[INFO] Get function (add) succeed." << endl;

    // 调用函数
    PyObject* pRet = PyObject_CallObject(pv, m_pArgs);

    // 获取结果
    long result = 0;
    if (pRet)  // 验证是否调用成功
    {
        result = PyInt_AsLong(pRet);
    }

    // 显示结果
    switch (type) {
    case Method_sum:
        m_pSumLE->setText(QString::number(result));
        break;
    case Method_sub:
        m_pSubLE->setText(QString::number(result));
        break;
    case Method_mul:
        m_pMulLE->setText(QString::number(result));
        break;
    case Method_div:
        m_pDivLE->setText(QString::number(result));
        break;
    case Method_mod:
        m_pModLE->setText(QString::number(result));
        break;
    default:
        break;
    }
}

void Widget::choosePythonFile()
{
    QString filename = QFileDialog::getOpenFileName(this, tr("选择文件"), ".", tr("Python File(*.py);;ALL FILE(*.*)"));
    if (!filename.isEmpty())
        m_pFileLE->setText(filename);
}

void Widget::calculate()
{
    QString filename = m_pFileLE->text();
    CallPython(filename);
}

pytest.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
def sum(a,b):
    print "a",a,"b",b
    print "sum:",a+b
    return a+b

def sub(a,b):
    print "a",a,"b",b
    print "sub:",a-b
    return a-b

def mul(a,b):
    print "a",a,"b",b
    print "mul:",a*b
    return a*b

def div(a,b):
    print "a",a,"b",b
    print "div:",a/b
    return a/b

def mod(a,b):
    print "a",a,"b",b
    print "mod:",a%b
    return a%b

参考资料:

浅析 C++ 调用 Python 模块

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值