I'm trying to run the example of item selection for a TableView, but it needs Qt.labs.qmlmodels. The problem is, that doesn't appear to be installed, and I can't find the correct package.
main.qml:
import Qt.labs.qmlmodels
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
ApplicationWindow {
visible: true
width: 1000
height: 700
title: "Test"
TableView {
id: tableView
anchors.fill: parent
clip: true
model: TableModel {
rows: [{
"name": "Harry"
}, {
"name": "Hedwig"
}]
TableModelColumn {
display: "name"
}
}
selectionModel: ItemSelectionModel {
model: tableView.model
}
delegate: Rectangle {
required property bool selected
implicitWidth: 100
implicitHeight: 30
color: selected ? "blue" : "lightgray"
Text {
text: display
}
}
}
}
main.py:
import sys
import signal
from PyQt6.QtGui import QGuiApplication
from PyQt6.QtQml import QQmlApplicationEngine
# Make app respond to Ctrl-C
signal.signal(signal.SIGINT, signal.SIG_DFL)
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.quit.connect(app.quit) # type: ignore
engine.load("main.qml")
sys.exit(app.exec())
Running main.py gives me this error:
QQmlApplicationEngine failed to load component
file:///home/user/test2/main.qml:1:1: module "Qt.labs.qmlmodels" is not installed
OS: Arch Linux
Qt version: 6.3.1-1
please read this:
qt-6.4-qml-python-missing-liberary-module-qt5compat-graphical-effects-is-not-installed
Just now, I try to change matplotlib-backends' version. I find that the pyqt6 folder doesn't have the Qt folder.
So I copy that in pyside6 lib to pyqt lib.
For me is:from D:\Python\Python39\Lib\site-packages\PySide6\qml\Qt to D:\Python\Python39\Lib\site-packages\PyQt6\Qt6\qml.
Please try this, hope it work.
Related
I am trying to communicate a python script to a qml ui using signal/slot and, while it works for some types (str) it seems to not be working when I try emitting a list:
Python:
from PySide6.QtCore import QObject, Signal, Slot
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
import time, sys
class PythonSignalEmitter(QObject):
getListTest = Signal(list)
#Slot()
def callList(self):
print("HELLO from python ")
test = ["a", "b", "c"]
self.getListTest.emit(test)
if __name__ == '__main__':
app = QGuiApplication([])
engine = QQmlApplicationEngine()
signal_emitter = PythonSignalEmitter()
engine.rootContext().setContextProperty("signalEmitter", signal_emitter)
engine.load("main.qml")
sys.exit(app.exec())
Fragment of the main.qml file:
Connections {
target: signalEmitter
function onSignal(res) {
console.log(`------------`);
console.log(`qml list is ${res}`);
console.log(`------------`);
}
}
The output of this just gives:
HELLO from python
So the app runs with no problem, and after a click on a specified component, the slot is called, but the log in the QLM side is not even printed, seems like the signal is not even emitted.
[EDIT]
You need to rename onSignal with onGetListTest. The rest is fine.
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Window
ApplicationWindow {
id: main
title: qsTr("Hello World")
width: 640
height: 480
visible: true
Frame {
anchors.centerIn: parent
RowLayout {
Button {
text: qsTr("Quit")
onClicked: Qt.callLater(Qt.quit)
}
Button {
text: qsTr("Test")
onClicked: signalEmitter.callList()
}
}
}
Connections {
target: signalEmitter
function onGetListTest(res) {
console.log(`------------`);
console.log(`qml list is ${res}`);
console.log(`------------`);
}
}
}
I want show charts in my app with Python back-end and qml front-end but I got an error.
Import:
import QtCharts 2.3
Error:
module "QtCharts" is not installed
I installed qtcharts with maintaince.exe
How to solve this?
In PyQt6 the chart module comes in a separate package and you must run:
python -m pip install PyQt6-Charts PyQt6
On the other hand maintaince.exe only works for C++ so installing QtCharts does not affect PyQt6.
In the next part there is a demo:
import os
from pathlib import Path
import sys
from PyQt6.QtCore import QCoreApplication, Qt, QUrl
from PyQt6.QtWidgets import QApplication
from PyQt6.QtQml import QQmlApplicationEngine
CURRENT_DIRECTORY = Path(__file__).resolve().parent
def main():
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
filename = os.fspath(CURRENT_DIRECTORY / "main.qml")
url = QUrl.fromLocalFile(filename)
def handle_object_created(obj, obj_url):
if obj is None and url == obj_url:
QCoreApplication.exit(-1)
engine.objectCreated.connect(
handle_object_created, Qt.ConnectionType.QueuedConnection
)
engine.load(url)
sys.exit(app.exec())
if __name__ == "__main__":
main()
import QtQuick
import QtQuick.Controls
import QtCharts
ApplicationWindow {
id: root
width: 640
height: 480
visible: true
title: qsTr("Login Page")
ChartView {
id: chartView
anchors.fill: parent
LineSeries {
XYPoint {
x: 0
y: 0
}
XYPoint {
x: 1.1
y: 2.1
}
}
}
}
Note: In Qt6 the versions of the QML modules should not be indicated.
I use Python and Pyside2, I try to insert a QQuickWidget inside a Qwidget or inside a Layout but I haven't find a solution.
I try with this code:
view = QQuickWidget()
view.setSource(QUrl.fromLocalFile("main.qml"))
but QQuickWidget start in another windows.
I try use:
Layout.addWidget(view)
but it required a QWidget and don't work with QQuickWidget.
I found this similar question (in C) but it don't work in Python:
Adding QQuickWidget in QStackedWidget
I have try QQmlApplicationEngine and QQuickView, but problem is the some.
Can you help me ?
Edit:
main.qml file is:
import QtQuick 2.0
import QtQuick.Window 2.0
import QtLocation 5.6
import QtPositioning 5.6
Window {
width: 300
height: 300
visible: true
Plugin {
id: mapPlugin
name: "esri"
}
Map {
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(39.2160, 9.1344)
zoomLevel: 16
}
}
The problem is that the root element is a Window that will create a window, the solution is to use an Item:
import QtQuick 2.0
import QtLocation 5.6
import QtPositioning 5.6
Item {
width: 300
height: 300
Plugin {
id: mapPlugin
name: "esri"
}
Map {
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(39.2160, 9.1344)
zoomLevel: 16
}
}
I got 3 Files in the same folder:
form.py
from __future__ import print_function
import sys, os
from PySide2.QtCore import QFile, QObject, QUrl
from PySide2.QtGui import QGuiApplication
from PySide2.QtQuick import QQuickView
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
qmlFile = os.path.join(os.path.dirname(__file__), 'Main.qml')
view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile)))
if view.status() == QQuickView.Error:
sys.exit(-1)
view.show()
app.exec_()
del view
Main.qml
import QtQuick 2.10
Item {
width: 200
height: 200
ListModel
{
id: myModel
ListElement { type: "Dog"; age: 8 }
ListElement { type: "Cat"; age: 5 }
}
ListView {
anchors.fill: parent
model: myModel
delegate: MyDelegate
}
}
MyDelegate.qml
import QtQuick 2.10
Component {
id: myDelegate
Text { text: type + ", " + age }
}
Running the form.py should give me a window with a ListView and two elements in it. This code is taken from an official tutorial and changed so I can see how referencing of QML files within other QML files works. All I get is a white window, so I guess the delegate does not get loaded by the Main.qml.
The first letter of MyDelegate.qml is uppercase so the Main.qml should automatically load the delegate. I expect this behaviour because it is a solution from the question: Include another QML file from a QML file
and in many tutorials, including some for PyQt5, I saw them referencing other QML files like that.
If I copy the Component {...} part into the Main.qml and change the delegate reference in ListView {...} from MyDelegate to myDelegate, it works.
This problem appears with any QML node I want to outsource into a separate file.
Doesn't PySide2 support this feature, or do I have to do some magic in the form.py to let the Main.qml know that there is another QML file to load?
I installed the current wheel with
pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.11/latest/ pyside2 --trusted-host download.qt.io
from the official wiki on a Windows 10 64bit machine with Python 3.6 installed.
Thanks to derM and eyllanesc who pointed out that there is a typo in the reference of MyDelegate.qml. The reference should be with braces delegate: MyDelegate {}.
The correct form.py is now:
import QtQuick 2.10
Item {
width: 200
height: 200
ListModel{
id: myModel
ListElement { type: "Dog"; age: 8 }
ListElement { type: "Cat"; age: 5 }
}
ListView {
anchors.fill: parent
model: myModel
delegate: MyDelegate {}
}
}
It even works with myModel outsourced in a MyModel.qml and referenced as model: MyModel {}
I am using pyqt and I have the following directory structure:
root
----> apps/
----> ui/
I have a simple qml based application in the app folder as:
apps/testqt.py
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQuick import QQuickView, QQuickWindow
from PyQt5.QtQml import qmlRegisterType, QQmlApplicationEngine
import sys
app = QApplication(sys.argv)
engine = QQmlApplicationEngine('ui/window.qml')
topLevel = engine.rootObjects()[0]
win = QQuickWindow(topLevel)
win.show()
app.exec_()
ui/window.qml
The qml file defines the app window and uses a StackView as follows:
import QtQuick 2.0
import QtQuick.Window 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
ApplicationWindow {
id: rootWindow
objectName: "window"
visible: true
width: 800
height: 480
title: "Window"
Component.onCompleted: {
setX(Screen.width / 2 - width / 2);
setY(Screen.height / 2 - height / 2);
}
property Component loginView: LoginView {}
StackView {
id: stackView
anchors.fill: parent
Component.onCompleted:
{
stackView.push(loginView)
}
}
}
This uses the LoginView component which is defined as:
apps/LoginView.qml
import QtQuick 2.0
import QtQuick.Window 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.0
ControlView {
ColumnLayout {
anchors.centerIn: parent
spacing: 25
width: 200
TextField {
id: username_fld
placeholderText: qsTr("User name")
Layout.fillWidth: true
}
TextField {
id: password_fld
placeholderText: qsTr("Password")
Layout.fillWidth: true
echoMode: TextInput.Password
}
RowLayout {
Button {
id: login_button
text: "Log In"
Layout.fillWidth: true
}
Button {
id: cancel_button
text: "Cancel"
Layout.fillWidth: true
}
}
}
}
Now when I use qmlscene, the view loads just fine. However, running python results in the application hanging while trying to load the QQmlApplicationEngine. I have a feeling it has something to do with the qml paths perhaps, so I included import ../ui into the window.qml imports but that did not change anything.
I am using Python 2.7 with Qt 5.6 in an Anaconda environment. Qt was installed from here: https://anaconda.org/anaconda/pyqt
Similarly i use multiple qml files along with multiple python files. When i access application it loads perfectly two qml files successfully but when stacked through third qml page, the application crashes. It throws segmentation fault.
I use Stackview to push and pop through QML pages, during debugging i found that it works when push and pop are done for just for two pages.
I have came across if i use Swipeview too. What i guess is that the engine that was created can be loaded with two stack QML files.