存在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")
)
答案 0 :(得分:0)
Cython没有实现MOC,因此QML无法调用这些方法(如果检查了生成的.c,则可以看到除MOC创建的@Slot之外,所有其他东西都已实现。)
一种解决方法是,在导入并使用插槽中的已编译代码之后,将使用该插槽的代码分开,并在该部分中使用cython。