一、PythonQt库

在Qt(C++)中与Python混合编程,可以使用PythonQt库。

网站首页:http://pythonqt.sourceforge.net

下载页面:https://sourceforge.net/projects/pythonqt/files/

只提供了源码下载,需自行编译。

版本要求:

其网站building页面上的要求:Qt 4.8.1以上,Python2.6以上

实际测试中得出的版本要求:Qt5.4以上,可以编译得到动态链接库(.so文件);Python2.7.12,编译范例程序成功。

(备注:我的测试环境是操作系统 Ubuntu 16.04 64bit,PythonQt版本:3.2)

二、编译与安装

1. 安装Qt

去Qt网站下载安装包,或者通过apt安装。安装完毕后,在命令行中执行qmake -v,查看输出信息,确认Qt已安装好。

注意:如果使用apt或者synaptic安装Qt,那么需要手动安装Qt的一些模块,例如multimedia等。以Qt5为例,其模块一般以libQt5为开头,可以用apt或synaptic搜索关键字安装。如果缺少模块,则编译时会报错提示。

2. 安装Python

用apt安装Python和Python-dev。Linux一般预装Python。

sudo apt install python python-dev

3. 编译

将下载的源码解压。进入解压目录,之后执行编译指令。假设解压目录为PythonQt

cd PythonQt

qmake

make all

编译可能需要花费几分钟,请耐心等待。

编译完成后,编译得到的库文件以及范例程序都在PythonQt/lib下。此时运行范例程序可能失败,需要先安装刚编译好的库。

4. 安装

所谓安装,是指让系统能够找到编译好的库文件。实现的方式有多种,这里介绍通过链接的方式安装。

首先确认系统中的库文件默认目录是什么。

cd /etc/ld.so.conf.d/

ls

可能列出一些配置文件,文件名是对应的目录,比如x86_64-linux-gnu.conf。用文本编辑器打开,就可以看到对应的完整目录。我的系统中默认库目录有

/lib/x86_64-linux-gnu

/usr/lib/x86_64-linux-gnu

这里,我选择/usr/lib/x86_64-linux-gnu这个目录安装。

#进入PythonQt的目录

cd PythonQt

#复制文件(文件名中的数字与版本有关,不一定和我一样)

sudo cp lib/libPythonQt-Qt5-Python2.7.so.3.2.0 /usr/lib/x86_64-linux-gnu

sudo cp lib/libPythonQt_QtAll-Qt5-Python2.7.so.3.2.0 /usr/lib/x86_64-linux-gnu

#进入安装目录

cd /usr/lib/x86_64-linux-gnu/

#创建链接

sudo ln -sf libPythonQt-Qt5-Python2.7.so.3.2.0 libPythonQt-Qt5-Python2.7.so

sudo ln -sf libPythonQt-Qt5-Python2.7.so.3.2.0 libPythonQt-Qt5-Python2.7.so.3

sudo ln -sf libPythonQt-Qt5-Python2.7.so.3.2.0 libPythonQt-Qt5-Python2.7.so.3.2

sudo ln -sf libPythonQt_QtAll-Qt5-Python2.7.so.3.2.0 libPythonQt_QtAll-Qt5-Python2.7.so

sudo ln -sf libPythonQt_QtAll-Qt5-Python2.7.so.3.2.0 libPythonQt_QtAll-Qt5-Python2.7.so.3

sudo ln -sf libPythonQt_QtAll-Qt5-Python2.7.so.3.2.0 libPythonQt_QtAll-Qt5-Python2.7.so.3.2

#更新

sudo ldconfig

安装完成。运行PythonQt/lib下的范例程序(双击或命令行执行),如果可以运行,说明正常。

三、在Qt项目中使用PythonQt

可以看范例源码和官方文档学习。这里以Linux(Ubuntu系)环境为例,简单介绍一下使用方法。

1. 新建项目

使用QtCreator新建项目。

2. 准备库文件

需要将一些配置文件和PythonQt库的头文件复制到项目文件夹下(可以新建一个子文件夹)。假设项目目录为[PRJ],PythonQt目录为[PYQ]。

cd [PRJ]

mkdir PythonQt

cp [PYQ]/src/PythonQt*.h PythonQt/

cp [PYQ]/build/*.prf ./

cp [PYQ]/lib/libPythonQt-Qt5-Python*.so* ./

其中.h是头文件,.prf是配置文件,.so是链接库。

头文件可以直接使用。配置文件需要修改,主要是修改相关目录。

说明:配置文件的注释方式是每行前加注释符号#。

以下是一种修改方式:

common.prf

将以下三行删除或注释掉:

CONFIG(debug, debug|release) {

TARGET = $${TARGET}_d

}

将所有的$$PWD/../改为$$PWD/。

PythonQt.prf

删除或注释掉以下内容:

INCLUDEPATH += $$PWD/../src

# check if debug or release

CONFIG(debug, debug|release) {

DEBUG_EXT = _d

} else {

DEBUG_EXT =

}

修改

unix::LIBS += -L$$PWD/../lib -lPythonQt-Qt5-Python$${PYTHON_VERSION}$${DEBUG_EXT}

改为

unix::LIBS += -L$$PWD -lPythonQt-Qt5-Python$${PYTHON_VERSION}$${DEBUG_EXT}

3. 修改.pro文件

在项目.pro文件中加入以下内容:

include ( common.prf )

include ( PythonQt.prf )

INCLUDEPATH += PythonQt

4. 在代码中调用PythonQt

这个可以参考PythonQt的范例,然后慢慢摸索。

首先,引用头文件

#include "PythonQt.h"

在使用PythonQt时,首先要对PythonQt的单例对象进行操作。包括初始化,获取对象等。

// init PythonQt and Python

PythonQt::init();

之后,获取__main__模块。

PythonQtObjectPtr mainModule;

// get the __main__ python module

mainModule = PythonQt::self()->getMainModule();

为了能看到python程序中的打印信息,需要连接PythonQt单例对象信号,与你自己写的槽。

// connect output signals

connect(PythonQt::self(), SIGNAL(pythonStdOut(const QString&)), this, SLOT(stdOut(const QString&)));

connect(PythonQt::self(), SIGNAL(pythonStdErr(const QString&)), this, SLOT(stdErr(const QString&)));

第一个信号是向std::out的输出,第二个信号是std::err的输出。

之后就可以操作mainModule的方法来调用python代码了。当然,如果python代码里不需要输出,也可以不连接上述信号。

四、执行Python语句或脚本

按照上一节的说明初始化后,就可以执行Python语句或调用Python脚本了。

1. evalScript——执行少量语句

如果要调用的python代码只有单一一行语句或者少量几语句,可以使用evalScript函数。该函数的参数是要执行的指令,返回执行结果。

QVariant result1 = mainModule.evalScript("19*2+4", Py_eval_input);

QVariant result2 = mainModule.evalScript("len([1, 2, 3])", Py_eval_input);

其中"19*2+4"是python语句,第二个参数表示执行的是独立的python表达式。返回类型是QVariant,可以根据实际执行的语句,转换成具体的数据类型。比如这里可以用QVariant::toInt()转换成int,得到的结果分别是42和3。不熟悉的朋友请参考QVariant文档。

evalScript 可以用于定义函数,方便以后调用。例如:

mainModule.evalScript("def add(a, b):\n return a+b");

这样就定义了一个Python中的函数,名为add,接受两个参数a和b,返回两个数的和。

后面第三部分介绍如何调用Python函数。

2. evalFile——执行脚本

如果需要使用Python实现较为复杂的功能,写在一个Python文件中比较方便。假设文件名为func.py。

Python文件的开头需要加入如下语句:

from PythonQt import *

在Qt项目中新建资源文件(.qrc文件),在资源文件中添加func.py,以便调用。调用方式为:

mainModule.evalFile(":/func.py");

调用时的文件路径与添加到资源文件时的前缀有关。注意evalFile没有返回类型,所以不能用于获得返回值,可以通过第四节所说的打印信息看到执行过程(如果Python程序中有输出语句的话)。如果是Qt GUI项目,也可以把执行结果显示在界面上,这一点在后面第四部分介绍。

执行过evalFile后,脚本中定义的函数可以在以后直接调用。所以可以把需要返回值的功能写在函数中,后续调用。调用方式见第三部分。

3. call——调用函数

前面介绍了,使用evalScript和evalFile都能定义Python函数。定义的函数会保存,之后可以在代码的任意位置调用。要调用这些函数,可使用call。例如第一点介绍中定义了一个Python中的函数,名为add,接受两个参数a和b,返回两个数的和。调用该函数的方法如下:

int a = 2;

int b = 3;

QVariant c = mainModule.call("add", QVariantList() << a << b);

call 的第一个参数是要调用的函数名称,用字符串表示;第二个参数是要调用的Python函数的参数,用一个QVariantList存放所有参数。这里,我们把a和b两个数传入。返回类型是QVariant,需要转换成具体类型。这里的c转换成整数后是5。

4. addObject——与Qt交互

如果Python程序需要与Qt中的对象交互,可以将继承自QObject的类型实例传入Python中。addObject就起到这个作用。

假设Qt GUI项目的mainwindow中有一个label,下面演示怎么通过Python改变label的文字。

首先将label传入Python(label的类型是QLabel,继承自QObject),并且赋予其一个在python中调用的变量名:

mainModule.addObject("label", ui->label);

这条语句将ui->label传入,并且在Python中可以用label这个变量名调用。

Python程序如下:

def changeLabelText(text):

label.text = text

通过evalScript或者evalFile调用上述程序后,再用call调用。

mainModule.evalFile(":/func.py");

mainModule.call("changeLabelText", QVariantList() << QString("Hello"));

mainModule.call("changeLabelText", QVariantList() << QString("World"));

第一次调用将标签文字改为Hello,第二次调用改为World。

在Python中操作QObject对象时,要注意,使用的方法、函数、属性等要用Python语法进行。例如在Qt(C++)中改变标签文字的方法是

label->setText("Hello");

而在Python中,应该使用

label.text = 'Hello'

5. Python模块路径问题

既然使用Python,可能是要使用Python中成熟的库,例如用于科学计算的NumPy。如果在Python程序中写入:

import numpy as np

可能在使用PythonQt执行的时候报错,说找不到numpy模块。(当然是已安装的情况下,在Python或命令行中都运行正常。)这很可能是路径问题。

首先找到numpy的安装路径,例如/usr/lib/python2.7/dist-packages。然后在需要调用的Python文件中加入如下语句:

import sys

sys.path.append('/usr/lib/python2.7/dist-packages') # To use Numpy

import numpy as np

这样就可以正常导入NumPy模块了。

小结

以上介绍了PythonQt库的安装和使用方法。

更加复杂的功能,请参考PythonQt源码中的范例,以及网站上的文档。

开发者文档:http://pythonqt.sourceforge.net/Developer.html

源码中也有很多有用信息,关于一些API函数的调用,可以参考头文件中的注释。例如,关于上面介绍的evalScript等函数,可以参考PythonQtObjectPtr.h文件(可用Qt Creator内的切换功能快速定位)。

qt如何用python结合_在Qt(C++)中与Python混合编程相关推荐

  1. php运行python爬虫_群晖系统中运行python爬虫程序

    重要:本文最后更新于2021-01-28 17:02:43,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗. 准备入手一台NAS,事先的学习是必须的,今天在VM虚拟机中安装好NAS后, ...

  2. flask执行python脚本_如何在Flask中运行python脚本

    我有一个Flask脚本,可以创建网站并动态打印一些数据.-打印的数据应来自另一个python脚本. 我目前面临的问题是,如果我将执行python脚本的行放在执行Flask应用程序的行之前,它将运行Py ...

  3. pycharm怎么编写python代码_如何设置PyCharm中的Python代码模版(推荐)

    在MacOs运行的PyCharm中,执行python文件,如果不指定python文件字符编码会报错: SyntaxError: Non-ASCII character '\xe6' in file / ...

  4. vscode怎么安装python库_如何在vscode中安装python库的方法步骤

    免费资源网 - https://freexyz.cn/ vscode安装python库 1.已经在vscode中装了python并配置好python运行环境. 检查是否正确配置好运行环境,按Windo ...

  5. arcgis andin使用python窗体_在ArcGIS?10中使用python

    导入模块 模块为通常包含函数和类的 Python 文件.有一系列模块支持 ArcPy,包括制图模块 (arcpy.mapping).Spatial Analyst 模块 (arcpy.sa) 和Geo ...

  6. pycharm终端运行python文件_在PyCharm终端中执行python manage.py..._慕课问答

    原来在DOS环境下需要先执行:  conda activate命令,然后再执行 python manage.py runserver就可以了. 如下: D:\DjangoProject\django_ ...

  7. sublime怎么配置python环境_在Sublime Editor中配置Python环境的详细教程

    导语在工作场景遇到了这么一个场景,就是需要定期去执行一个缓存接口,用于同步设备配置.首先想到的就是Linux上的crontab,可以定期,或者间隔一段时间去执行任务.但是如果你想要 2020-12-1 ...

  8. vscode写python爬虫_如何在vscode中调试python scrapy爬虫

    HDOJ 2393. Higher Math Higher Math Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/327 ...

  9. python 云计算_云计算开发学习笔记:Python的环境搭建

    大家都知道学好Python是进入云计算领域的基础,那么在学习之前我们先来了解下Python环境是如何搭建的.Python可应用于多种平台,包括大家熟悉的Window,Linux 和 Mac OS X. ...

最新文章

  1. 对于STM32F103控制的三轴机械臂基本功能测试-关节转动控制
  2. feign整合sential,Feign中使用Sentinel熔断器防止服务雪崩
  3. 面试官系统精讲Java源码及大厂真题 - 16 ConcurrentHashMap 源码解析和设计思路
  4. openstack租户管理_几大OpenStack的精华问答 | OpenStack都有哪些基础服务?
  5. 关于php单引号和双引号
  6. 【转】缺陷与出路—一个游戏开发者的反思
  7. ie升级后必须重启计算机吗,微软迟到的补丁:升级到IE9将无需重启计算机
  8. 人工智能几行代码实现换脸,python+dlib实现图文教程
  9. [转]真正了解CSS3背景下的@font face规则
  10. SVN和Git的使用
  11. 数字IC设计入门(9)初识数字芯片验证
  12. 18位身份证校验代码
  13. python打印文档添加条码_使用Python在Excel中批量生成条形码
  14. 如何通过美股交易软件完成开户?美股开户交易要点有哪些?
  15. mysqli assoc php,关于php:mysqli_fetch_assoc()期望参数1为mysqli_result,给定布尔值
  16. OpenCV基础(4)使用OpenCV裁剪图像
  17. 海湾crt调试_海湾设备调试步骤
  18. 8421码,5421码,2421码,余3码特点及转换
  19. jQuery事件 笔记
  20. 网易我的世界服务器怎么显示键盘,网易我的世界指令怎么用(常见的指令及使用方式)...

热门文章

  1. 关于ABAP流程处理的一些命令的说明(stop,exit,return,check,reject)
  2. 利用SAP内置功能生成Search Help
  3. “奶茶第一股”香飘飘,“香”不起来了?
  4. 时代天使点燃口腔赛道,瑞尔集团离下一只“牙茅”还有多远?
  5. echarts无数据时显示无数据_钣金无腻子数据还原
  6. ppt复制切片器_这6个新手必学的PPT技能,让你效率提升10倍!套模板都比别人快...
  7. c语言顺序表有效元素长度,C语言版数据结构顺序表的问题
  8. java的外部引用_Java 调用外部程序
  9. Buuctf(pwn) picoctf_2018_rop chain 栈溢出
  10. Buuctf(misc) 后门查杀