首页 > 编程语言 >PythonQt简明教程

PythonQt简明教程

时间:2024-01-04 16:00:55浏览次数:26  
标签:教程 封装 Python 简明 PythonQt C++ QObject CObject

PythonQt简明教程

PythonQt是Qt框架的Python动态绑定,是一种将Python脚本语言嵌入C++ Qt应用程序的简便方法。与PyQt、PySide不同,PythonQt侧重点在于将Python嵌入到现有的C++应用程序,而不是使用Python编写应用程序。


接口

PythonQt的主要接口通过PythonQt::self()单例提供,并由PythonQt::init()初始化。完整的Qt绑定通过PythonQt_QtAll::init()启用。


数据类型映射

Qt/C++ Python
bool bool
double float
float float
char/uchar,int/uint,short,ushort,QChar integer
long integer
ulong,longlong,ulonglong long
QString unicode string
QByteArray QByteArray封装器
char* str
QStringList unicode字符串元组
QVariantList objects元组
QVariantMap objects字典
QVariant 视类型而定
QSize, QRect及其它所有标准Qt变体类型 变体封装器,支持对应Qt类完整接口
OwnRegisteredMetaType C++封装器,registerCPPClass提供额外的信息、封装
QList<AnyObject*> 转换为C++封装器列表
QVector<AnyObject*> 转换为C++封装器列表
枚举类型 枚举封装器
QObject (及其子类) QObject封装器
C++对象 C++封装器,可由PythonQtCppWrapperFactory封装,或由装饰器装饰
PyObject PyObject
  • QStringRef(Qt5)、QStringViewQAnyStringView(Qt6)的处理方式与QString类似
  • QByteArrayView(Qt6)的处理方式类似于QByteArray
  • Python bytes 类型可以自动转换为QByteArray。而QByteArray则通过data()方法转换为bytes
  • QVariant类型将递归映射
  • PyObject是直接作为指针传递的,这允许将任何Python对象直接传递、返回到使用PyObject *作为参数、返回值的Qt槽函数

PythonQt实现了所有Qt QVariant类型,并支持这些对象的完整Qt API。


QObject封装

所有在Python解释器中可见的QObject子类,都会自动用一个Python类封装。即

  • 调用PythonQt::addObject
  • 槽函数在python中返回一个QObject子类
  • 信号函数包含一个QObject子类并连接到python函数

任何在Python可见的QObject子类,除了通过PythonQt::addObject()添加之外,调用PythonQt::registerClass()也非常重要。PythonQt::registerClass()将注册该类完整的父类层次结构,亦即当注册子类时,子类的所有父类都将被注册。 在Python中,不仅可以调用QObject对象的槽函数,还可以访问对象所有的属性。除此之外,还支持:

  • className() 返回QObject对象类名字符串
  • help() 打印对象的所有属性、槽、枚举、构造函数、封装器槽
  • delete() 删除对象
  • connect(signal, function) 连接信号与python函数
  • connect(signal, qobject, slot) 连接信号与另一QObject对象槽
  • disconnect(signal, function) 断开信号与python函数
  • disconnect(signal, qobject, slot) 断开信号与另一QObject对象槽
  • children() 返回子对象列表
  • setParent(QObject) 设置父对象
  • QObject *parent() 获取父对象

使用信号

# 定义信号处理函数
def someFunction(flag):
  print flag
 
# button1是通过addObject()添加到Python的QPushButton对象
# 连接clicked信号到Python函数
button1.connect("clicked(bool)", someFunction)

定义信号、槽

class MySender(QtCore.QObject):
  emitProgress = QtCore.Signal(float)  # 此float在C++中对应double
  
class MyReceiver(QtCore.QObject):
  @QtCore.Slot(float)
  def progress(self, value):
    print(f"progress: {value}")
 
sender = MySender()
receiver = MyReceiver()
# 通过有效签名连接
sender.connect("emitProgress(double)", receiver, "progress(double)")
sender.emitProgress(2.0)

C++封装

通过如下步骤,实现对C++类的封装:

  • 继承QObject并封装C++对象
class CObjectWrapper : public QObject
{
public:
    CObjectWrapper(void *object) : object(object) {}

public slots:
    // 方法

private:
    CObject *object;
};
  • 派生PythonQtCppWrapperFactory,实现create()方法
class CObjectFactory : public PythonQtCppWrapperFactory 
{
public:
    virtual QObject* create(const QByteArray& name, void *ptr)
    {
        if (name == "CObject")
            return new CObjectWrapper(ptr);
        return nullptr;
    }
};
  • 注册工厂
PythonQt::self()->addWrapperFactory(new CObjectFactory);

对于未知的C++类对象,PythonQt将创建一个通用的C++封装器。如果是支持的C++类对象,将通过封装器工厂创建对应的QObject封装器。除此之外,还可以通过装饰器实现。


元对象、元类型

对于每个已知的C++类,PythonQt都提供了对应的Python类,这些类在PythonQt模块中可见。如果注册类时给出了包名,则在子包中也可见。 元类型支持:

  • 访问所有已声明的枚举值
  • 构造函数
  • 静态方法
  • 非绑定非静态方法
  • help()className()

在Python中,可以通过导入PythonQt模块来访问这些类和Qt命名空间。

from PythonQt import QtCore
 
# 访问命名空间
print QtCore.Qt.AlignLeft
 
# 构造函数
a = QtCore.QSize(12,13)
b = QtCore.QFont()
 
# 静态方法
QtCore.QDate.currentDate()
 
# 枚举值
QtCore.QFont.UltraCondensed
# 或
QtCore.QFont.Stretch.UltraCondensed

装饰器

装饰器是PythonQt引入的一种扩展封装QObject、C++对象的方法,是提供了具有构造函数、析构函数等功能,并按约定命名的槽函数的QObject子类。

命名约束如下:

  • 构造函数 Class *new_Class(Args... args)
  • 析构函数 void delete_Class(Class *object)
  • 静态方法 ReturnType static_Class_method(Args... args)
  • 方法 ReturnType method(Class *object, Args... args)
// C++类实例
class CObject {
public:
    CObject(int arg1, float arg2) { a = arg1; b = arg2; }
 
    float method(int arg1) { return arg1 * a * b; };

private: 
    int a;
    float b;
};
 
// 装饰器实例,可以同时装饰多个C++类
class Decorator : public QObject
{
    Q_OBJECT
public slots:
  // 构造器
  YourCPPObject* new_CObject(int arg1, float arg2) { return new CObject(arg1, arg2); }
 
  // 析构器
  void delete_CObject(CObject* obj) { delete obj; }
 
  // 方法
  int method(CObject* obj, int arg1) { return obj->method(arg1); }
};
 
PythonQt::self()->addDecorators(new Decorator());
PythonQt::self()->registerCPPClass("CObject");
from PythonQt import QtCore, QtGui, CObject
 
# 调用构造函数
object = CObject(1,11.5)
 
# 调用方法
print object.method(1);
 
# 调用析构函数
object = None

所有权管理

在PythonQt中,当一个对象由Python构造函数创建是,默认归Python所有;当它从C++接口(如槽)返回时,默认归C++所有。 由于Qt接口中存在各种将所有权传递给其它C++对象的方法,因此PythonQt提供了如下接口来跟踪这些接口调用。

  • PythonQtPassOwnershipToCPP 传递所有权给C++
  • PythonQtPassOwnershipToPython 传递所有权给Python
  • PythonQtNewOwnerOfThis 建立新的所有权

这些注解模板适用于所有C++指针类型及QList<AnyObject *>

public slots:
    PythonQtPassOwnershipToPython<QGraphicsItem*> createNewItemOwnedByPython();
 
    void addItemToCPP(PythonQtPassOwnershipToPython<QGraphicsItem*> item);
    void addItemToCPP(PythonQtPassOwnershipToPython<QList<QGraphicsItem*>> items);
    void addItemParent(QGraphicsItem* wrappedObject, PythonQtNewOwnerOfThis<QGraphicsItem*> parent);

标签:教程,封装,Python,简明,PythonQt,C++,QObject,CObject
From: https://blog.51cto.com/u_15990474/9102079

相关文章

  • 无涯教程-Seaborn - 统计估计
    在大多数情况下,无涯教程处理数据整体分布的估计,但是,当涉及集中趋势估计时,需要一种特定的方式来汇总分布。均值和中位数是估计分布的集中趋势的常用技术。在上一节中学习的所有图中,都对整个分布进行了可视化。现在,讨论关于可以用来估计分布的集中趋势的图。BarPlotbarplot()......
  • 基于TIC6000的DSP教学实验箱操作教程:5-18 RGB24图像灰度转换(LCD显示)
    一、实验目的学习RGB24图像灰度转换的原理,掌握图像的读取方法,并实现在LCD上显示灰度转换前后的图像。二、实验原理RGB24图像灰度转换RGB颜色空间作为一种常用的彩色图像表示模型,分别用红(R)、绿(G)、蓝(B)三原色的组合来表示每个像素的颜色。一般情况下,RGB彩色图像灰度化有三种转化方案:(1)......
  • 无涯教程-Seaborn - 观察值分布
    在上一章中处理的类别散点图中,该方法在它可以提供的有关每个类别中值的分布的信息方面受到限制,现在,让无涯教程看看什么可以进行类别比较。BoxPlotsBoxPlots是通过四分位数可视化数据分布的便捷方法,BoxPlots通常具有从框延伸的垂直线,称为晶须。这些晶须表示上下四分位数之外......
  • 无涯教程-Seaborn - 直方图(Histogram)
    直方图表示数据分布,方法是沿数据范围形成条形图,然后绘制条形图以显示落入每个条形图的观察数。Seaborn附带了一些数据集,在前几章中只使用了很少的数据集。无涯教程已经学习了如何加载数据集以及如何查找可用数据集列表。importpandasaspdimportseabornassbfrommatplot......
  • 无涯教程-Seaborn - 密度估计(KDE)
    核密度估计(KDE)是一种估计连续随机变量的概率密度函数的方法,用于非参数分析。在distplot中将hist标志设置为False将产生内核密度估计图。importpandasaspdimportseabornassbfrommatplotlibimportpyplotaspltdf=sb.load_dataset('iris')sb.distplot(df['petal_l......
  • Conda命令、Miniconda3基础安装使用教程
    Conda命令、Miniconda3基础安装使用教程Minicodna3下载地址:https://docs.conda.io/projects/miniconda/en/latest/index.html正常安装完毕后,出现conda的控制台:默认的源下载太慢,换清华源,依次执行以下命令:condaconfig--addchannelshttps://mirrors.tuna.tsinghua.edu.cn/anaconda......
  • 无涯教程-Seaborn - 环境设置
    在本章中,无涯教程将讨论Seaborn的环境设置,从安装开始,在本节中,无涯教程将了解安装Seaborn所涉及的步骤。Pip安装要安装最新版本的Seaborn,可以使用pip-pipinstallseabornConda安装Anaconda(来自https://www.anaconda.com/是免费的Python发行版,用于SciPy堆栈,也可用于Linux......
  • 无涯教程-jsoup - 设置属性
    下面的示例将HTML解析为Document对象后,使用addClass或removeClass方法来增加或删除class类方法。Documentdocument=Jsoup.parse(html);Elementlink=document.select("a").first();link.attr("href","www.yahoo.com");link.addClass("header"......
  • 无涯教程-jsoup - 提取属性
    以下示例将HTML解析为Document对象后,使用Elements方法来获取dom元素的属性。Documentdocument=Jsoup.parse(html);Elementlink=document.select("a").first();System.out.println("Href:"+link.attr("href"));元素对象代表dom元素,并提供了各种获取dom元素属性的方法。......
  • 无涯教程-jsoup - 使用选择器语法
    以下示例将HTML解析为Document对象之后使用Selector方法操作元素,jsoup支持类似于CSSSelector选择器。Documentdocument=Jsoup.parse(html);//awithhrefElementslinks=document.select("a[href]");document.select(expression)方法解析给定的CSSSelector表达式,以选择ht......