Qt5 / PyQt5:带有 QML 前端和 Python 后端的自定义 QML 组件

Qt5 / PyQt5 : Custom QML components with QML frontend and Python backend

如果有意义的话,我想创建一个带有 python "backend" 的 QML 模块。基本上,我想使用 QML 来定义组件的外观,然后在 python class 中实现特定的行为,这应该扩展这个 QML-Type 并且 - 在我的想象中 - 在某种程度上必须可以链接到QML 组件。

我了解如何在 python 中创建自定义 class 并通过 qmlRegisterType 将其提供给 QML。到目前为止这是有效的,但是所有的绘图都必须在 class 本身中实现 ​​- 没有 QML

(基本上,我想要的是用 kv 语言在 kivy 中完成的方式)

一个小例子:

我实现了一个简单的 ColorPicker 小部件,如下所示:

class ColorWheel(QLabel):
    radius = 0

    color_changed = pyqtSignal(float, float)

    def __init__(self, width, height):
        super().__init__()

        pixmap = QPixmap("colorwheel.png").scaled(width, height)

        self.setFixedSize(width, height)
        self.setPixmap(pixmap)
        self.radius = width / 2

    def mouseReleaseEvent(self, event):
        # {...} get mouse position, calc polar corrdinates (omitted)
        # emit signal: new color was selected
        self.color_changed.emit(r, angle)

    def get_polar(self, x, y):
        # {...} calculate polar coordinates for HSV color space (omitted)
        return r, theta

现在我想将 GUI 代码(像素图绘图等)移动到 QML 文件 ColorWheel.qml,如下所示:

import QtQuick 2.0
Item {
    Image {
        id: img
        anchors.fill: parent
        source: "./colorwheel.png"  
    }
}

在主 QML 文件中 main.qml 然后我想做这样的事情:

import QtQuick 2.2
import ColorWheel 1.0

ApplicationWindow {
    title: qsTr("Test Invoke")
    width: 500
    height: 400

    ColorWheel {
        radius: 200
    }
}

这可能吗?我在 Qt 和 pyQt 文档中找不到任何相关信息。它总是关于使 C++ classes 可用于 QML 或其他方式...

有人能指出我正确的方向吗?

非常感谢!

如果您从 QQuickItem 继承并注册它 - 它显然会像 Item {}.

如果您在 C++/python 端添加一些属性 - 它将是具有属性的 Item

ColorWheelImpl.h(相当于python):

class ColorWheelImpl: public QQuickItem
{
...
};
...
qmlRegisterType<ColorWheelImpl>("com.mycompany.myitems", 1, 0, "ColorWheelImpl");

在 Python 中,qmlRegisterType 语法类似于:

qmlRegisterType(ColorWheelImpl, 'com.mycompany.myitems', 1, 0, 'ColorWheelImpl')

ColorWheel.qml:

import QtQuick 2.0
import com.mycompany.myitems 1.0
ColorWheelImpl {
    Image {
        id: img
        anchors.fill: parent
        source: "./colorwheel.png"  
    }
}