QML 中的自定义对象引用 Python
Custom object referencing in QML Python
我正在尝试使用 qmlRegisterType 扩展 QML。我有一个 python class - PyQml.py, main.qml 文件和样板代码它。
问题是我无法在 main.qml 文件中引用(导入)PyQml 对象,出现错误 --> QML module not found (PyQml) 。
到目前为止,我已经确定了 QML_IMPORT_PATH 个变量路径。由于我是 hopelles,我在其中一个路径中创建了名为 PyQml 的文件夹,其中包含 PyQml.py 但仍然没有成功。此外,我在 Qt Creator 项目中找不到 *.pro 文件。我想我应该为我的自定义对象添加另一个路径。
PyQml.py
class PyQml(QObject):
def __init__(self, parent=None):
super().__init__(parent)
# Initialise the value of the properties.
self._name = ''
self._shoeSize = 0
# Define the getter of the 'name' property. The C++ type of the
# property is QString which Python will convert to and from a string.
@Property('str')
def name(self):
return self._name
# Define the setter of the 'name' property.
@name.setter
def name(self, name):
self._name = name
# Define the getter of the 'shoeSize' property. The C++ type and
# Python type of the property is int.
@Property(int)
def shoeSize(self):
return self._shoeSize
# Define the setter of the 'shoeSize' property.
@shoeSize.setter
def shoeSize(self, shoeSize):
self._shoeSize = shoeSize
qmlengine.py
import sys
import sqlite3
from PySide2 import QtCore, QtGui, QtWidgets, QtQuick
from PySide2.QtCore import Qt,QUrl
from PySide2.QtQml import QQmlApplicationEngine,qmlRegisterType
from PySide2.QtGui import QGuiApplication
from ViewModel import PyQml
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
print(QQmlApplicationEngine.importPathList(engine))
ctx = engine.rootContext()
ctx.setContextProperty("qmlapp", engine) #the string can be anything
qmlRegisterType(PyQml.PyQml, 'People', 1, 0, 'Person');
engine.load('Documents/ctmd/Qml/main.qml')
win = engine.rootObjects()[0]
win.show()
sys.exit(app.exec_())
main.qml
import QtQuick 2.0
import QtQuick.Controls 1.4
import PyQml 1.0 ---- Error QML module not found ( PyQml)
ApplicationWindow {
menuBar: MenuBar {
Menu {
title: "File"
MenuItem { text: "Open..." }
MenuItem { text: "Close" }
}
Menu {
title: "Edit"
MenuItem { text: "Cut" }
MenuItem { text: "Copy" }
MenuItem { text: "Paste" }
}
}
Grid {
columns: 3
spacing: 2
Rectangle { color: "red"; width: 50; height: 50 }
Rectangle { color: "green"; width: 20; height: 50 }
Rectangle { color: "blue"; width: 50; height: 20 }
Rectangle { color: "cyan"; width: 50; height: 50 }
Rectangle { color: "magenta"; width: 10; height: 10 }
}
}
项目文件夹树
Qml
-main.qml
PyQml.py
qmlengine.py
PyQml 只是一个示例 class,在一天结束时我想传递我在 python(x,y 坐标)中计算的自定义数据并使用 qml[=15 绘制该数据=]
TL;DR; 没有消除错误消息的解决方案,因为它是 QtCreator 与 Qt for Python 的限制。但是 QtCreator 只是一个 IDE 所以它不需要在那里工作,相反你只需要 运行 来自 console/CMD:
的代码
python /path/of/script.py
您有以下错误:
当你用qmlRegisterType注册一个QObject时,"People"是QML中的包名,"Person"是组件名,所以你不应该在PyQml中使用导入,除非您更改注册表参数。
QtCreator/QtQuickDesigner 对 Python 的支持仍有局限性,因此消息:"Qml module not found (FooPackage)" 是此示例.正如 Python/PySide2 的 Qt 开发人员指出的那样,他们将在未来的版本中添加新功能,但目前还不可能。
我看到您在出版物中指出的结构与您的项目不匹配,因为例如您指出 main.qml 位于 QML 文件夹中,该文件夹与qmlengine.py 但在负载中你使用 "Documents/ctmd/Qml/main.qml".
PySide2 对 属性 装饰器及其 setter 有限制,因为 QML 无法识别它,而是使用广泛的声明:name_of_property = Property(type_of_property, fget = getter_of_property, ...)
如果 Qt 属性 带有 setter 那么它必须有关联的信号。
综合以上,解决方案是:
├── PyQml.py
├── Qml
│ └── main.qml
└── qmlengine.py
qmlengine.py
import os
import sys
from PySide2.QtCore import QUrl
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType
import PyQml
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
qmlRegisterType(PyQml.PyQml, "People", 1, 0, "Person")
engine = QQmlApplicationEngine()
ctx = engine.rootContext()
ctx.setContextProperty("qmlapp", engine) # the string can be anything
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "Qml/main.qml")
engine.load(QUrl.fromLocalFile(filename))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
PyQml.py
from PySide2.QtCore import Property, Signal, QObject
class PyQml(QObject):
nameChanged = Signal(str)
shoeSizeChanged = Signal(int)
def __init__(self, parent=None):
super().__init__(parent)
# Initialise the value of the properties.
self._name = ""
self._shoeSize = 0
# Define the getter of the 'name' property. The C++ type of the
# property is QString which Python will convert to and from a string.
def get_name(self):
return self._name
# Define the setter of the 'name' property.
def set_name(self, name):
if self._name != name:
self._name = name
self.nameChanged.emit(name)
name = Property(str, fget=get_name, fset=set_name, notify=nameChanged)
# Define the getter of the 'shoeSize' property. The C++ type and
# Python type of the property is int.
def get_shoeSize(self):
return self._shoeSize
# Define the setter of the 'shoeSize' property.
def set_shoeSize(self, shoeSize):
if self._shoeSize != shoeSize:
self._shoeSize = shoeSize
self.shoeSizeChanged.emit(shoeSize)
shoeSize = Property(
int, fget=get_shoeSize, fset=set_shoeSize, notify=shoeSizeChanged
)
main.qml
import QtQuick 2.0
import QtQuick.Controls 1.4
import People 1.0
ApplicationWindow {
visible: true
Person{
name: "foo"
shoeSize: 10
}
menuBar: MenuBar {
Menu {
title: "File"
MenuItem { text: "Open..." }
MenuItem { text: "Close" }
}
Menu {
title: "Edit"
MenuItem { text: "Cut" }
MenuItem { text: "Copy" }
MenuItem { text: "Paste" }
}
}
Grid {
columns: 3
spacing: 2
Rectangle { color: "red"; width: 50; height: 50 }
Rectangle { color: "green"; width: 20; height: 50 }
Rectangle { color: "blue"; width: 50; height: 20 }
Rectangle { color: "cyan"; width: 50; height: 50 }
Rectangle { color: "magenta"; width: 10; height: 10 }
}
}
我发现如果我简单地忽略这个错误
在 qml window 中一切正常。我什至尝试重新安装 IDE,错误仍然存在。谢谢你的澄清。
我正在尝试使用 qmlRegisterType 扩展 QML。我有一个 python class - PyQml.py, main.qml 文件和样板代码它。 问题是我无法在 main.qml 文件中引用(导入)PyQml 对象,出现错误 --> QML module not found (PyQml) 。
到目前为止,我已经确定了 QML_IMPORT_PATH 个变量路径。由于我是 hopelles,我在其中一个路径中创建了名为 PyQml 的文件夹,其中包含 PyQml.py 但仍然没有成功。此外,我在 Qt Creator 项目中找不到 *.pro 文件。我想我应该为我的自定义对象添加另一个路径。
PyQml.py
class PyQml(QObject):
def __init__(self, parent=None):
super().__init__(parent)
# Initialise the value of the properties.
self._name = ''
self._shoeSize = 0
# Define the getter of the 'name' property. The C++ type of the
# property is QString which Python will convert to and from a string.
@Property('str')
def name(self):
return self._name
# Define the setter of the 'name' property.
@name.setter
def name(self, name):
self._name = name
# Define the getter of the 'shoeSize' property. The C++ type and
# Python type of the property is int.
@Property(int)
def shoeSize(self):
return self._shoeSize
# Define the setter of the 'shoeSize' property.
@shoeSize.setter
def shoeSize(self, shoeSize):
self._shoeSize = shoeSize
qmlengine.py
import sys
import sqlite3
from PySide2 import QtCore, QtGui, QtWidgets, QtQuick
from PySide2.QtCore import Qt,QUrl
from PySide2.QtQml import QQmlApplicationEngine,qmlRegisterType
from PySide2.QtGui import QGuiApplication
from ViewModel import PyQml
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
print(QQmlApplicationEngine.importPathList(engine))
ctx = engine.rootContext()
ctx.setContextProperty("qmlapp", engine) #the string can be anything
qmlRegisterType(PyQml.PyQml, 'People', 1, 0, 'Person');
engine.load('Documents/ctmd/Qml/main.qml')
win = engine.rootObjects()[0]
win.show()
sys.exit(app.exec_())
main.qml
import QtQuick 2.0
import QtQuick.Controls 1.4
import PyQml 1.0 ---- Error QML module not found ( PyQml)
ApplicationWindow {
menuBar: MenuBar {
Menu {
title: "File"
MenuItem { text: "Open..." }
MenuItem { text: "Close" }
}
Menu {
title: "Edit"
MenuItem { text: "Cut" }
MenuItem { text: "Copy" }
MenuItem { text: "Paste" }
}
}
Grid {
columns: 3
spacing: 2
Rectangle { color: "red"; width: 50; height: 50 }
Rectangle { color: "green"; width: 20; height: 50 }
Rectangle { color: "blue"; width: 50; height: 20 }
Rectangle { color: "cyan"; width: 50; height: 50 }
Rectangle { color: "magenta"; width: 10; height: 10 }
}
}
项目文件夹树
Qml
-main.qml
PyQml.py
qmlengine.py
PyQml 只是一个示例 class,在一天结束时我想传递我在 python(x,y 坐标)中计算的自定义数据并使用 qml[=15 绘制该数据=]
TL;DR; 没有消除错误消息的解决方案,因为它是 QtCreator 与 Qt for Python 的限制。但是 QtCreator 只是一个 IDE 所以它不需要在那里工作,相反你只需要 运行 来自 console/CMD:
的代码python /path/of/script.py
您有以下错误:
当你用qmlRegisterType注册一个QObject时,"People"是QML中的包名,"Person"是组件名,所以你不应该在PyQml中使用导入,除非您更改注册表参数。
QtCreator/QtQuickDesigner 对 Python 的支持仍有局限性,因此消息:"Qml module not found (FooPackage)" 是此示例.正如 Python/PySide2 的 Qt 开发人员指出的那样,他们将在未来的版本中添加新功能,但目前还不可能。
我看到您在出版物中指出的结构与您的项目不匹配,因为例如您指出 main.qml 位于 QML 文件夹中,该文件夹与qmlengine.py 但在负载中你使用 "Documents/ctmd/Qml/main.qml".
PySide2 对 属性 装饰器及其 setter 有限制,因为 QML 无法识别它,而是使用广泛的声明:
name_of_property = Property(type_of_property, fget = getter_of_property, ...)
如果 Qt 属性 带有 setter 那么它必须有关联的信号。
综合以上,解决方案是:
├── PyQml.py
├── Qml
│ └── main.qml
└── qmlengine.py
qmlengine.py
import os
import sys
from PySide2.QtCore import QUrl
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType
import PyQml
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
qmlRegisterType(PyQml.PyQml, "People", 1, 0, "Person")
engine = QQmlApplicationEngine()
ctx = engine.rootContext()
ctx.setContextProperty("qmlapp", engine) # the string can be anything
current_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(current_dir, "Qml/main.qml")
engine.load(QUrl.fromLocalFile(filename))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
PyQml.py
from PySide2.QtCore import Property, Signal, QObject
class PyQml(QObject):
nameChanged = Signal(str)
shoeSizeChanged = Signal(int)
def __init__(self, parent=None):
super().__init__(parent)
# Initialise the value of the properties.
self._name = ""
self._shoeSize = 0
# Define the getter of the 'name' property. The C++ type of the
# property is QString which Python will convert to and from a string.
def get_name(self):
return self._name
# Define the setter of the 'name' property.
def set_name(self, name):
if self._name != name:
self._name = name
self.nameChanged.emit(name)
name = Property(str, fget=get_name, fset=set_name, notify=nameChanged)
# Define the getter of the 'shoeSize' property. The C++ type and
# Python type of the property is int.
def get_shoeSize(self):
return self._shoeSize
# Define the setter of the 'shoeSize' property.
def set_shoeSize(self, shoeSize):
if self._shoeSize != shoeSize:
self._shoeSize = shoeSize
self.shoeSizeChanged.emit(shoeSize)
shoeSize = Property(
int, fget=get_shoeSize, fset=set_shoeSize, notify=shoeSizeChanged
)
main.qml
import QtQuick 2.0
import QtQuick.Controls 1.4
import People 1.0
ApplicationWindow {
visible: true
Person{
name: "foo"
shoeSize: 10
}
menuBar: MenuBar {
Menu {
title: "File"
MenuItem { text: "Open..." }
MenuItem { text: "Close" }
}
Menu {
title: "Edit"
MenuItem { text: "Cut" }
MenuItem { text: "Copy" }
MenuItem { text: "Paste" }
}
}
Grid {
columns: 3
spacing: 2
Rectangle { color: "red"; width: 50; height: 50 }
Rectangle { color: "green"; width: 20; height: 50 }
Rectangle { color: "blue"; width: 50; height: 20 }
Rectangle { color: "cyan"; width: 50; height: 50 }
Rectangle { color: "magenta"; width: 10; height: 10 }
}
}
我发现如果我简单地忽略这个错误
在 qml window 中一切正常。我什至尝试重新安装 IDE,错误仍然存在。谢谢你的澄清。