qml文件无法将函数调用到pyd文件

时间:2018-12-24 08:33:18

标签: python qt qml cython pyside2

存在qml文件无法调用pyd文件的问题。

有几个文件:

i。 main.py-> python.exe运行条目

ii。 mainWidget.py->显示MyItem.qml ui并将setContextProperty设置为MyItem.qml

iii。 MyItem.qml->单击鼠标区域时,将在mainWidget.py中调用MyObect函数“ cppMethod”和“ cppSlot”

iv。 setup.py->构建扩展文件以生成使用的pyd

v。 mainWidget.pyd->由Cython生成

在mainWidget.py中,存在MyObject类,在该类中,函数“ cppMethod”和“ cppSlot”将在python.exe上打印日志

然后我调用“ setContextProperty”函数将“ myobject”注册到MyItem.qml,以便MyItem.qml识别“ myobject”对象。

当我在python.exe上运行main.py时,它将显示一个小部件。 尝试单击此窗口小部件,它将调用MyObect函数“ cppMethod”和“ cppSlot”。它起作用了!

它将显示:

qml: start
call the c++ method with Hello from QMLTest
call the c++ slot with 12345
qml: end

在那之后,我尝试保护代码,因此我使用Cython(带有setup.py)来生成文件“ mainWidget.pyd”。

所以我将mainWidget.pyd替换为mainWidget.py。

当我使用带有“ mainWidget.pyd”的python.exe运行main.py时,我在小部件中单击鼠标区域,它将显示

"TypeError: Property 'cppMethod' of object MyObject(0x21822d07430) is not a function".

这意味着MyItem.qml无法识别“ myobject”。

有什么办法可以解决这个问题?如何解决此问题?

ps。我使用Python版本3.6.2,Qt版本5.6.2

main.py

import mainWidget
widget = mainWidget.main()

mainWidget.py

import os
import sys
import PySide2
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import QApplication, QWidget
from PySide2.QtQuickWidgets import *

class MyObject(PySide2.QtCore.QObject):
    def __init__(self, parent=None):
        super(MyObject, self).__init__(parent)

    @PySide2.QtCore.Slot(str)
    def cppMethod(self, msg):
        print ("call the c++ method with ",msg)

    @PySide2.QtCore.Slot(int)
    def cppSlot(self, number):
        print ("call the c++ slot with", number)

def main():
    app = QApplication(sys.argv)
    view = QQuickWidget()
    myclass = MyObject()
    view.rootContext().setContextProperty("myObject",myclass)
    relativeUrl = QUrl(".//MyItem.qml")
    view.setSource(relativeUrl)
    view.show()
    sys.exit(app.exec_())

MyItem.qml

import QtQuick 2.5
import QtQuick.Controls 1.5
import QtQuick.Layouts 1.3
import QtQuick.Controls.Styles 1.4
import QtQml 2.2

Item {
    width: 100; height: 100
    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.log("start")
            myObject.cppMethod("Hello from QML")
            myObject.cppSlot(12345)
            console.log("end")
        }
    }
}

setup.py

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("mainWidget.py")
)

1 个答案:

答案 0 :(得分:0)

Cython没有实现MOC,因此QML无法调用这些方法(如果检查了生成的.c,则可以看到除MOC创建的@Slot之外,所有其他东西都已实现。)

一种解决方法是,在导入并使用插槽中的已编译代码之后,将使用该插槽的代码分开,并在该部分中使用cython。