Pyside createObject() Bug
-
I am porting this javascript tutorial into pyside (for some reason its in pyside doc but not actually written in python):
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_4And am having difficulty calling the createObject() method of a QDeclarativeComponent object that gets called whenever it is time to make a new block for this "samegame" example.
Here is my pyside game logic module (normally javascript in the above tutorial):
@ import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtDeclarative import *
from math import floorclass MainWindow(QDeclarativeView): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setWindowTitle("Main Window") # Renders 'view.qml' self.setSource(QUrl.fromLocalFile('game.qml')) # QML resizes to main window self.setResizeMode(QDeclarativeView.SizeRootObjectToView) self.blockSize = 40 self.maxColumn = 10 self.maxRow = 15 self.maxIndex = self.maxColumn * self.maxRow self.board = [] self.component = None #Index function used instead of a 2D array def index(self, column, row): return column + (row * self.maxColumn) @Slot() def startNewGame(self): #Delete blocks from previous game for b in self.board: b.destroy() bgnd = self.rootObject().findChild(QDeclarativeItem, name="background") width = QDeclarativeProperty(bgnd, "width") height = QDeclarativeProperty(bgnd, "height") #Calculate board size self.maxColumn = int(floor(width.read() / self.blockSize)) self.maxRow = int(floor(height.read() / self.blockSize)) self.maxIndex = self.maxColumn * self.maxRow #Initialize Board self.board = [None for _ in range(self.maxIndex)] for column in range(self.maxColumn): for row in range(self.maxRow): self.createBlock(column, row) def createBlock(self, column, row): if self.component is None: engine = QDeclarativeEngine() self.component = QDeclarativeComponent(engine, QUrl.fromLocalFile("Block.qml")) # Note that if Block.qml was not a local file, component.status would be # Loading and we should wait for the component's statusChanged() signal to # know when the file is downloaded and ready before calling createObject(). if self.component.isReady(): bgnd = self.rootObject().findChild(QDeclarativeItem, name="background") print bgnd dynamicObject = self.component.createObject(bgnd) if dynamicObject is None: print "error creating block" return False dynamicObject.x = column * self.blockSize dynamicObject.y = row * self.blockSize dynamicObject.width = self.blockSize dynamicObject.height = self.blockSize self.board[self.index(column, row)] = dynamicObject else: print "error loading block component" return False return True if __name__ == '__main__': # Create the Qt Application app = QApplication(sys.argv) # Create and show the main window window = MainWindow() context = window.rootContext() context.setContextProperty("tester",window) window.show() # Run the main Qt loop sys.exit(app.exec_())@
Note: All necessary QML files use QtQuick 1.0 and are identical to the tutorial so I dont repeat them here.
When I run this code, it crashes at:
@ dynamicObject = self.component.createObject(bgnd)@
with:
@ TypeError: Unknown type used to call meta function (that may be a signal): QScriptValue@
any ideas how I'm misusing this createObject method? I understand the parent must be a QObject and that it is not optional. Otherwise, I'm not entirely able to understand from the docs what more it should constitute:
http://srinikom.github.io/pyside-docs/PySide/QtDeclarative/QDeclarativeComponent.html
Thanks!