将 C++ 类移植到 PyQt

Posted

技术标签:

【中文标题】将 C++ 类移植到 PyQt【英文标题】:Port C++ class to PyQt 【发布时间】:2015-08-04 10:03:00 【问题描述】:

我正在尝试将用 C++ 编写的 Qt4 自定义小部件转换为 Python 2.7 自定义小部件。但是,我无法弄清楚如何用 Python 编写 QLabel(parent)。这是“.ccp”文件中的原始 C++ 代码:

DocumentWidget::DocumentWidget(QWidget *parent)
    : QLabel(parent)

    currentPage = -1;
    setAlignment(Qt::AlignCenter);

QLabel(parent) 似乎是某种初始化列表。我曾尝试在 Python 中并行使用多重继承,但这会导致以下错误:Cannot create a consistent method resolution order (MRO) for bases QLabel, QWidget

我正在尝试移植代码而不是为 C++ 小部件创建包装器,因为我不懂 C++,并且认为我将来必须进一步自定义小部件。

我没有接受过程序员培训,这是我第一次接触 C++,所以即使我在做一些愚蠢的事情,请随时纠正我。我不会感到尴尬。

【问题讨论】:

该符号用于调用基类的构造函数 (like this),因此它等效于 calling super. __init__ 是的,看起来差不多。 【参考方案1】:

代码为DocumentWidget 类定义了一个构造函数,它继承QLabel 并需要QWidget 作为父类。

等效的 PyQt 代码是:

from PyQt4 import QtCore, QtGui

class DocumentWidget(QtGui.QLabel):
    def __init__(self, parent):
        super(DocumentWidget, self).__init__(parent)
        # or QtGui.QLabel.__init__(self, parent)
        self.currentPage = -1
        self.setAlignment(QtCore.Qt.AlignCenter)

【讨论】:

通常parent 是可选的,所以它应该类似于def __init__(self, parent = None) @PavelStrakhov。是的,当然 - 但它不会是严格等价的(即 C++ 签名不是QWidget * parent = 0)。它目前不是可选的可能有充分的理由(可能某些方法需要访问父级)。但无论如何,我认为移植代码的第一阶段应该始终非常保守,并且旨在纯语法。这使得通过直接针对 C++ 原始版本测试 python 版本更容易发现回归。设计更改可以稍后进行。 使用这种方法,如何将 QWidget 作为父级传递?当我打电话给DocumentWidget(QWidget) 我得到argument 1 has unexpected type 'PyQt4.QtCore.pyqtWrapperType' @ColinLee。您没有传递 class,而是传递了该类的 instance。所以你可能有一个QMainWindow(它是QWidget 的子类),它的一个方法创建文档小部件的实例,如下所示:docwidget = DocumentWidget(self)【参考方案2】:

多重继承有效,但必须以正确的顺序调用基类(即DocumentWidget(QLabel, QWidget) 而不是DocumentWidget(QLabel, QWidget))。

全文:

from PyQt4.QtCore import *
from PyQt4.QtGui import *

class DocumentWidget(QLabel, QWidget):
    def __init__(self, parent=None):
        super(DocumentWidget, self).__init__()
        self.currentPage = -1
        self.setAlignment(Qt.AlignCenter)

【讨论】:

这段代码是错误的,只有“有效”,因为QLabelQWidget 的子类。 Qt 几乎只使用 single 继承,所以你不应该尝试在 PyQt 中使用多重继承。大多数时候,这样做只会产生错误。在这种情况下,继承QWidget 只是多余的,所以你应该删除它。此外,您必须使用super 调用来执行__init__(parent),否则将不起作用。可以通过None(这是默认值),因为QLabel 只是可选地需要一个父级。

以上是关于将 C++ 类移植到 PyQt的主要内容,如果未能解决你的问题,请参考以下文章

将 python 代码移植到 C++ /(在 C++ 中打印出数组)

将 GNU C++ 程序移植到 Visual C++

将 32 位 C++ 代码移植到 64 位 - 值得吗?为啥?

如何将 Ubuntu C++ 库移植到 MinGW?

将 SDL 示例移植到 OpenGL 和 C++

将 Visual C++ 项目移植到 C# [关闭]