Reputation: 11
Currently working on a Python program that uses Qt Widgets from an .ui file to display an interactable GUI. However, i have not found a way to integrate the QQuickview widget to display any QML code, which i have read is possible.
I'm using PySide2 to convert the .ui file from Qt Designer and have both attempted to use the QQuickWidget found in Qt Designer, and manualy adding a QQuickView to the gridLayout in the .ui to no success.
The QQuickWidget i added in Qt Designer was, as far as i could tell transformed to a QWidget when run in python, so setSource(QUrl) or .load(QUrl) Made no sense when running the code.
My attempt at adding the QQuickView:
def connect_map_click(self):
# Function for handling the connect map button
engine = QQuickView()
ctx = engine.rootContext()
url = QUrl.fromLocalFile('QMLtest.qml')
engine.setSource(url)
container = QWidget.createWindowContainer(engine, self)
container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
engine.show()
self.window.grd_map.addWidget(container, 0, 0)
The QML file:
import QtQuick 2.7
Rectangle {
id: rectangle
color: "red"
width: 200
height: 200
visible: true
Text {
id:text
text: "It's working!"
}
}
I'm attempting to run the qml window on the right side of the screen, shown below.
Upvotes: 0
Views: 758
Reputation: 244003
QQuickView is a local variable that will be deleted when "connect_map_click" is finished executing nothing in the container.
The solution is to extend the life cycle and for this there are the following alternatives:
def connect_map_click(self):
engine = QQuickView(self.window.grd_map.parentWidget().window().windowHandle())
# ...
# ...
container = QWidget.createWindowContainer(engine, self)
container.engine = engine
# ...
or the self
:
def connect_map_click(self):
# Function for handling the connect map button
self.engine = QQuickView()
ctx = self.engine.rootContext()
url = QUrl.fromLocalFile('QMLtest.qml')
self.engine.setSource(url)
container = QWidget.createWindowContainer(self.engine, self)
container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
engine.show()
self.window.grd_map.addWidget(container, 0, 0)
Notes:
As you point out another solution is to use QQuickWidget since its life cycle depends on your parent who is self so he will live as long as the class. But QQuickWidget has limitations as the docs points out, including that you will not be able to record items that may be one of your requirements.
This behavior happens in PySide2 but in PyQt5 your initial code works since the container passes as parent to the QWindow of the window.
Upvotes: 0
Reputation: 11
Solved it myself as one tends to do right after asking for help.
Ended up finding out that i had not imported the QQuickWidget to the Python file before. So my solution ended up being to create a QQuickWidget in python, setting the source to the qml file and adding it to the grid in the .ui GUI.
def connect_map_click(self):
# Function for handling the connect map button
qml_widget = QtQuickWidgets.QQuickWidget()
qml_widget.setSource(QUrl('QMLtest.qml'))
self.window.grd_map.addWidget(qml_widget)
Upvotes: 0