如何在Pyside中动态实例化QML项目

时间:2014-02-19 03:31:22

标签: python qt qml pyside qt-quick

建立这个Pyside教程: http://qt-project.org/wiki/PySide_QML_Tutorial_Advanced_1 http://qt-project.org/wiki/PySide_QML_Tutorial_Advanced_2 http://qt-project.org/wiki/PySide_QML_Tutorial_Advanced_3 http://qt-project.org/wiki/PySide_QML_Tutorial_Advanced_4

我正在尝试用Python做所有事情而没有任何java脚本。

我遇到的唯一困难是调用QDeclarativeComponent的createObject()方法时,这里很好地描述为“动态对象管理”: http://qt-project.org/doc/qt-4.8/qdeclarativedynamicobjects.html

所以这是一个导致错误的简单例子:

import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtDeclarative import *

class MainWindow(QDeclarativeView):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("Main Window")
        # Renders game screen
        self.setSource(QUrl.fromLocalFile('game2.qml'))
        # QML resizes to main window
        self.setResizeMode(QDeclarativeView.SizeRootObjectToView)
        # a qml object I'd like to add dynamically
        self.component = QDeclarativeComponent(QDeclarativeEngine(), QUrl.fromLocalFile("Block2.qml"))
        # check if were ready to construct the object
        if self.component.isReady():
            # create the qml object dynamically
            dynamicObject = self.component.createObject(self.rootObject())

if __name__ == '__main__':
    # Create the Qt Application
    app = QApplication(sys.argv)
    # Create and show the main window
    window = MainWindow()
    window.show()
    # Run the main Qt loop
    sys.exit(app.exec_())

使用主窗口QML文件内容(“game2.qml”):

import QtQuick 1.0

Rectangle {
    id: screen

    width: 490; height: 720

    SystemPalette { id: activePalette }
}

和QML对象我想动态构造(“Block2.qml”):

import QtQuick 1.0

Rectangle {
    id: block
}

当我运行此代码时,它崩溃在:

dynamicObject = self.component.createObject(self.rootObject())

使用:

TypeError: Unknown type used to call meta function (that may be a signal): QScriptValue

我理解父母必须是QObject,否则我不完全确定文档应该构成什么: http://srinikom.github.io/pyside-docs/PySide/QtDeclarative/QDeclarativeComponent.html

根据以下内容,这不是C ++中的问题: https://qt-project.org/forums/viewthread/7717

这显然只是Pyside目前的一个问题。

知道可能导致此问题的原因是什么?潜在的错误?

1 个答案:

答案 0 :(得分:0)

解决方法是依靠javascript来创建对象,而其他一切都是python。在此实现中,您将组件的qml文件及其父级传递给创建组件的javascript实现。它做了对象的基本构造。为了简洁起见,使用纯python解决方案将是理想的。

import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtDeclarative import *

class MainWindow(QDeclarativeView):

def __init__(self, parent=None):
    super(MainWindow, self).__init__(parent)
    self.setWindowTitle("Main Window")
    # Renders game screen
    self.setSource(QUrl.fromLocalFile('game2.qml'))
    # QML resizes to main window
    self.setResizeMode(QDeclarativeView.SizeRootObjectToView)
    # a qml object I'd like to add dynamically
    parent = self.rootObject()
    view = QDeclarativeView()
    view.setSource(QUrl.fromLocalFile("comp_create.qml"))
    block = view.rootObject().create("Block2.qml", parent)
    print block
    block.x = 100
    block.y = 200
    # prove that we created the object
    print block.x, block.y

if __name__ == '__main__':
    # Create the Qt Application
    app = QApplication(sys.argv)
    # Create and show the main window
    window = MainWindow()
    window.show()
    # Run the main Qt loop
    sys.exit(app.exec_())

唯一添加的QML是一个组件创建者,它使用javascript创建对象,因为Pyside当前不能工作(“comp_create.qml”):

import QtQuick 1.0

Item {
    id: creator

     function create(qml_fname, parent) {
         // for a given qml file and parent, create component
         var comp = Qt.createComponent(qml_fname);
         if (comp.status == Component.Ready) {
             // create the object with given parent
             var ob = comp.createObject(parent);
             if (ob == null) {
                 // Error Handling
                 console.log("Error creating object");
             }
             return ob
         } else if (component.status == Component.Error) {
             // Error Handling
             console.log("Error loading component:", component.errorString());
         }
         else {
             component.statusChanged.connect(finishCreation);
         }
         return null
     } 
}

注意,借用此代码主要来自: http://qt-project.org/doc/qt-4.8/qdeclarativedynamicobjects.html