Why won't QQuickWidget work (Python / PySide2)?
-
Hi there. I have a test QML file and I am trying to embed it into a QMainWindow based application. For the life of me I cannot make the QML appear and I have followed every example I can find. This interface is created in Qt Creator and is a simple Main Window application with nothing but a linear layout in the window.
from ui_interface import * import sys from PySide2 import * from PySide2.QtQuickWidgets import QQuickWidget class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) mapView = QQuickWidget() mapView.setSource(QUrl.fromLocalFile("test_qml_box.qml")) self.ui.map_layout.addWidget(mapView) self.show() if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec_())
test_qml_box.qml:
import QtQuick 2.9 import QtQuick.Window 2.2 import QtQuick.Controls 2.2 Item{ Rectangle{ id:rect1 color:"yellow" anchors.fill: parent Text { id: sampleText1 text: qsTr("This text should appear") font.family: "Arial" font.pointSize: 50 anchors.rightMargin: 0 anchors.bottomMargin: 0 anchors.fill: parent verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } } } /*##^## Designer { D{i:0;autoSize:true;height:480;width:640} } ##^##*/
ui_interface.py:
# -*- coding: utf-8 -*- ################################################################################ ## Form generated from reading UI file 'qml_test2CqRmgR.ui' ## ## Created by: Qt User Interface Compiler version 5.15.2 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ from PySide2.QtCore import * from PySide2.QtGui import * from PySide2.QtWidgets import * class Ui_MainWindow(object): def setupUi(self, MainWindow): if not MainWindow.objectName(): MainWindow.setObjectName(u"MainWindow") MainWindow.resize(800, 600) self.centralwidget = QWidget(MainWindow) self.centralwidget.setObjectName(u"centralwidget") self.horizontalLayout_2 = QHBoxLayout(self.centralwidget) self.horizontalLayout_2.setSpacing(0) self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) self.map_layout = QHBoxLayout() self.map_layout.setObjectName(u"map_layout") self.horizontalLayout_2.addLayout(self.map_layout) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(MainWindow) self.menubar.setObjectName(u"menubar") self.menubar.setGeometry(QRect(0, 0, 800, 21)) MainWindow.setMenuBar(self.menubar) self.statusbar = QStatusBar(MainWindow) self.statusbar.setObjectName(u"statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow) # setupUi def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None)) # retranslateUi
-
Hi,
I just tested this simpler version with PySide6 (qml file with the same content) on macOS:
import sys from PySide6.QtCore import QUrl from PySide6.QtWidgets import QApplication from PySide6.QtWidgets import QMainWindow from PySide6.QtQuick import QQuickWindow from PySide6.QtQuickWidgets import QQuickWidget from PySide6.QtQuick import QSGRendererInterface class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) mapView = QQuickWidget() mapView.setSource(QUrl.fromLocalFile("test_qml_box.qml")) self.setCentralWidget(mapView) self.show() if __name__ == "__main__": app = QApplication(sys.argv) QQuickWindow.setGraphicsApi(QSGRendererInterface.OpenGL) window = MainWindow() window.show() sys.exit(app.exec())
and it shows something. Can you test it on your side ?
By the way, which version of PySide2 are you using ?
On which OS ?
How did you install it ? -
Python was installed on Windows 10 with the installer. Then I installed PyCharm and did pip install PySide2 and PyQtDesigner. UI design was done with designer.exe from that install. I wasn't sure about using PySide6 because the designer.exe produces an interface with PySide2. This is the first time I have used Qt Designer but quite frankly, it seemed to be very difficult install PyQt/PySide/Qt Designer/Qt Creator with everything matching. Previously I had done my interfaces manually but every example I was seeing used Designer so I figured I would give it a whirl. Also I want other UI controls around this QML and I am unclear on how to extend your simple example to do that. It seems that setting the central widget for the entire QMainWindow as the QQuickWidget would be an impediment to doing that and goes against the design I'm getting from Designer, but I eventually I need this QML to be a map from QLocation which seems to require QML based on the only examples provided in the Qt documentation.
I would be fine with starting with this simple code and building up the interface from there, but I am unsure of how to get a Qt Designer that will generate a PySide6 file and meet my requirements. Designer did not seem to come automatically with PySide and the version in PyQtDesigner generates PySide2. Nor could I find a simple windows or mac install for Designer or Creator. Although it just occurred to me that I could probably unwrap the ui file within the code with any of these libraries instead of generating the Python with Designer, but it still seems like using the QML widget as the central widget would be limiting.
To be quite honest, I found the documentation on all of this quite sparse and there aren't very many examples on the internet either. Any hints you could give me on using the right combination of Qt/Designer to utilize QLocation mapping while being able to use a QMainWindow application would be most appreciated.
Here is my pip freeze:
astroid==2.11.6 autopep8==1.6.0 branca==0.5.0 certifi==2022.6.15 charset-normalizer==2.1.0 colorama==0.4.5 dill==0.3.5.1 flake8==4.0.1 folium==0.12.1.post1 idna==3.3 isort==5.10.1 jedi==0.18.1 Jinja2==3.1.2 lazy-object-proxy==1.7.1 MarkupSafe==2.1.1 mccabe==0.6.1 numpy==1.23.0 packaging==21.3 parso==0.8.3 platformdirs==2.5.2 pluggy==1.0.0 pycodestyle==2.8.0 pydocstyle==6.1.1 pyflakes==2.4.0 pylint==2.14.4 pyparsing==3.0.9 PyQt5==5.15.7 PyQt5-Qt5==5.15.2 PyQt5-sip==12.11.0 PyQtWebEngine==5.15.6 PyQtWebEngine-Qt5==5.15.2 PySide2==5.15.2.1 python-lsp-jsonrpc==1.0.0 python-lsp-server==1.4.1 pytoolconfig==1.1.2 requests==2.28.1 rope==1.2.0 shiboken2==5.15.2.1 snowballstemmer==2.2.0 toml==0.10.2 tomli==2.0.1 tomlkit==0.11.0 ujson==5.3.0 urllib3==1.26.9 wrapt==1.14.1 yapf==0.32.0
-
Designer is just generating .ui files.
There's an intermediate tool called uic (with possible prefix depending on which Python bindings you are using) that will generate the Python code from these files.
Personally I build the UI fully in code.
I don't know what your final design is but if your main UI is in QML then there's no need for a designer based widget to show it.
-
Yes I did see uic in one example, and I was going to try that with Pyside6. If that doesn't work, I will explore using all QML.
The reason why I didn't want to use QML is because I am performing websockets communication through Python libraries and I didn't know if QML would satisfy all my needs or if I could back it with Python for the communication. I want to have a couple sliding drawers for navigation and options, and I knew how to do that with widgets but wasn't sure if QML was able to . I will look into the full QML interface option.