Using QtCharts in Qt Creator with python - python

I am using Qt Creator to create a QtQuick program using Python. I want to add the QtCharts module to my QML files, but I get the error message
QML module not found (QtCharts)
In a QtQuick project using C++, one would include QtCharts by adding QT += charts in the .pro file.
Is there a similar command to add in the main.pyproj file?
Note that the program runs correctly when built through the python script, but I want to access the features used by the designer in Qt Creator.
The main.pyproject is as follows:
{"files": ["main.py","frontend/main.qml"]}
The main.py file:
import os
import sys
import PyQt5.QtQml
import PyQt5.QtCore
import PyQt5.QtWidgets
if __name__ == '__main__':
os.environ['QT_QUICK_CONTROLS_STYLE'] = 'Default'
app = PyQt5.QtWidgets.QApplication(sys.argv)
engine = PyQt5.QtQml.QQmlApplicationEngine()
engine.load('frontend/main.qml')
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
the frontend/main.qml file:
import QtQuick 2.12
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.12
import QtCharts 2.10
ApplicationWindow {
id: window
visible: true
title: 'Neuron Network Sandbox'
ChartView {
width: 400
height: 300
antialiasing: true
PieSeries {
id: pieSeries
PieSlice { label: "eaten"; value: 94.9 }
PieSlice { label: "not yet eaten"; value: 5.1 }
}
}
}

Related

PySide6 QQmlApplicationEngine failed to load component

Hello I designed an my UI using Qt Design Studio (Community Edition) and exported it to a qrc file then compiled to Python using pyside6-rcc then loaded the main.qml file inside main.py using "qrc:/main.qml" resource link but I have these errors Type App not available.
This is my file structure;
- qml
- contents
* App.qml
* ... // Other Files
+ imports
* main.qml
* uifiles.qrc
* uifiles.py // Generated by [pyside6-rcc uifiles.qrc -o uifiles.py]
* main.py
Content of qml/content/App.qml;
import QtQuick
import QtQuick.Window
import "qrc:/content"
import QtQuick.VirtualKeyboard
Window {
width: mainScreen.width
height: mainScreen.height
visible: true
title: "IntelUI"
Screen01 {
id: mainScreen
}
InputPanel {
id: inputPanel
property bool showKeyboard : active
y: showKeyboard ? parent.height - height : parent.height
Behavior on y {
NumberAnimation {
duration: 200
easing.type: Easing.InOutQuad
}
}
anchors.leftMargin: Constants.width/10
anchors.rightMargin: Constants.width/10
anchors.left: parent.left
anchors.right: parent.right
}
}
Content of qml/main.qml;
import QtQuick
import "qrc:/content"
App {
}
Content of main.py;
import sys
import qml.uifiles
from PySide6.QtCore import QUrl
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load(QUrl("qrc:/main.qml"))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec())
Errors generated by python main.py;
QQmlApplicationEngine failed to load component
qrc:/main.qml:7:1: Type App unavailable
qrc:/content/App.qml:42:5: Type Screen01 unavailable
qrc:/content/Screen01.ui.qml:41:13: Type MainStream unavailable
qrc:/content/MainStream.ui.qml:12:1: module "QtQuick.Studio.Components" is not installed
Note: I have the following installed PySide6, PySide6-Addons
Any help will useful. Thank You!

How to use MapType in qml?

I am working on a gui project in python, where i want to show a map using pyqt.
I've stumbled upon a way of using qml to do just that, and I was able to show a simple map, but when I try customizing it's appearance using the activeMapType property, the program only show a blank white screen. (I dont have debug messages, cause I'm not using Qt creator)
I suspect a problem is in the declaration of "map_type", but i can't figure what it is.
The python code (simply loads the qml file):
import os
from PyQt5 import QtCore, QtWidgets, QtQuickWidgets, QtPositioning
from PyQt5.QtQuick import QQuickView
from PyQt5.QtWidgets import *
if __name__ == '__main__':
app = QApplication([])
w = QtQuickWidgets.QQuickWidget()
qml_path = os.path.join(os.path.dirname(__file__), "main.qml")
w.setSource(QtCore.QUrl.fromLocalFile(qml_path))
w.setResizeMode(QtQuickWidgets.QQuickWidget.SizeRootObjectToView)
w.show()
app.exec()
Main.qml:
import QtQuick 2.11
import QtPositioning 5.11
import QtLocation 5.11
Rectangle {
id:rectangle
width: 640
height: 480
Plugin {
id: osmPlugin
name: "osm"
}
MapType {
id: map_type
description: "type of the map"
mobile: false
name: "test"
night: true
}
property variant locationTC: QtPositioning.coordinate(44.951, -93.192)
Map {
id: map
activeMapType: map_type
anchors.fill: parent
plugin: osmPlugin
center: locationTC
zoomLevel: 10
copyrightsVisible: false
}
}

Testing QML based app with pytest in python

I would like to test my QML frontend code along with my Python backend code(using PySide2) with Pytest preferably, and be able to send keyClicks, MouseClicks and signals just like pytest-qt plugin does. I have already checked out pytest-qml, but the test code is written via QML, and then only ran via via pytest, but I would like to send events and such from python itself, not QML
Basically, having the python code as such:
"""
Slots, Signals, context class etc etc...
"""
app = QGuiApplication([])
engine = QQmlApplicationEngine()
engine.load(QUrl.fromLocalFile("main.qml"))
app.exec_()
and a simple main.qml file, as such,
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.2
import QtQuick.Controls 2.15
ApplicationWindow {
id: mywin
width: Screen.desktopAvailableWidth
height: Screen.desktopAvailableHeight
visible: true
FileDialog {
id: openDialog
title: "mydialog"
onAccepted: {
}
}
Button {
objectName: "mybtn"
width: 200
height: 200
id: btn
text: "hello"
onClicked: {
openDialog.open()
}
}
}
I would like to do (pseudo-code)something like
def test_file_open():
#Grab QQuickItem(btn)
#Send mouse event to click btn
#Send string to file dialog
# assert string sent == string selected
The pytest-qt plugin would work, but functions take QWidget and QML deals with QQuickItems, which as far as I know doesnt deal with QWidgets.
Is it even possible, or my only option to test my app slots etc is via the pytest-qml ? Perhaps its the easiest way, but perhaps there are other options :)
Edit:
If you use import Qt.labs.platform 1.1 instead of the import QtQuick.Dialogs 1.3, and force QML to not use native dialog, then just change
# assert myfiledialog.property("fileUrl").toLocalFile() == filename # uses QDialog
assert myfiledialog.property("currentFile").toLocalFile() == filename # using QLabs Dialog
And then using the rest of the code from accepted answer it will work, so apparently its very important that it does not use a native dialog.
If anyone else in the future knows how to make it work with native dialog and using QtQuick.Dialogs 1.3 as the original question presented, it would be nice :). But this is still nice to test overall!
You can use the same API since pytest-qt is based on QtTest. Obviously you must understand the structure of the application, for example that the FileDialog is just a QObject that only manages a QWindow that has the dialog, in addition to managing the positions of the items with respect to the windows.
import os
from pathlib import Path
from PySide2.QtCore import QUrl
from PySide2.QtQml import QQmlApplicationEngine
CURRENT_DIR = Path(__file__).resolve().parent
def build_engine():
engine = QQmlApplicationEngine()
filename = os.fspath(CURRENT_DIR / "main.qml")
url = QUrl.fromLocalFile(filename)
engine.load(url)
return engine
def main():
app = QGuiApplication([])
engine = build_engine()
app.exec_()
if __name__ == "__main__":
main()
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.15
import QtQuick.Window 2.2
ApplicationWindow {
id: mywin
width: Screen.desktopAvailableWidth
height: Screen.desktopAvailableHeight
visible: true
FileDialog {
id: openDialog
objectName: "myfiledialog"
title: "mydialog"
onAccepted: {
}
}
Button {
id: btn
objectName: "mybtn"
width: 200
height: 200
text: "hello"
onClicked: {
openDialog.open();
}
}
}
import os
from PySide2.QtCore import QCoreApplication, QObject, Qt, QPointF
from PySide2.QtGui import QGuiApplication
from PySide2.QtQuick import QQuickItem
from PySide2.QtWidgets import QApplication
import pytest
from app import build_engine
#pytest.fixture(scope="session")
def qapp():
QCoreApplication.setOrganizationName("qapp")
QCoreApplication.setOrganizationDomain("qapp.com")
QCoreApplication.setAttribute(Qt.AA_DontUseNativeDialogs)
yield QApplication([])
def test_app(tmp_path, qtbot):
engine = build_engine()
assert QCoreApplication.testAttribute(Qt.AA_DontUseNativeDialogs)
with qtbot.wait_signal(engine.objectCreated, raising=False):
assert len(engine.rootObjects()) == 1
root_object = engine.rootObjects()[0]
root_item = root_object.contentItem()
mybtn = root_object.findChild(QQuickItem, "mybtn")
assert mybtn is not None
center = QPointF(mybtn.width(), mybtn.height()) / 2
qtbot.mouseClick(
mybtn.window(),
Qt.LeftButton,
pos=root_item.mapFromItem(mybtn, center).toPoint(),
)
qtbot.wait(1000)
qfiledialog = None
for window in QGuiApplication.topLevelWindows():
if window is not root_object:
qfiledialog = window
assert qfiledialog is not None, QGuiApplication.topLevelWindows()
file = tmp_path / "foo.txt"
file.touch()
filename = os.fspath(file)
for letter in filename:
qtbot.keyClick(qfiledialog, letter, delay=100)
qtbot.wait(1000)
qtbot.keyClick(qfiledialog, Qt.Key_Return)
qtbot.wait(1000)
myfiledialog = root_object.findChild(QObject, "myfiledialog")
assert myfiledialog is not None
assert myfiledialog.property("fileUrl").toLocalFile() == filename
Note: The test may fail if the filedialog uses the native window, you could use tools like pyinput but a simpler option is to use virtualenv.

PySide6 comes with segmentation fault on Mac

I am using Python 3.8.6 and PySide 6.0.1 and get a segmentation fault running the below sample.
When I comment the Text {} element the sample runs.
import sys
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine("view.qml")
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
import QtQuick 2.0
import QtQuick.Controls 2.5
ApplicationWindow
{
width: 640
height: 480
visible: true
title: "QML Demo"
Text
{
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: "Hello World"
}
}
I can't test your code on Mac but as a suggestion you can remove all version numbers from imports in QML.
This is the only difference I can see here between PyQt5 and PyQt6.
(however your code works on Ubuntu 20.04)

Failed to build graphics pipeline state in qt quick application

I have a qt quick pyside application .I had a question before,but now another proplem is there .Just a empty window appears and then in application window I see below message.Although I have another qt quick application that I written that in c++ and there is no problem displaying it, this message is displayed!,This application is in python(pyside6)
I use Qt 6.0.2,Python 3.9.2,Qt Creator 4.14.1 and Pyside6
Failed to create vertex shader: Error 0x80070057: The parameter is incorrect.
Failed to build graphics pipeline state
*main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window {
id:mainWindow
width: 1000
height: 580
visible: true
title: qsTr("JooyaTrader")
Rectangle{
width: 152
height: 62
anchors.fill: parent
color: "red"
}
}
main.py
import sys,os
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
import PySide6
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load(os.path.join(os.path.dirname(__file__), "main.qml"))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
The problem is caused because the backend that Qt Quick uses for rendering does not work for your case, either because there are missing libraries or the version is not according to what Qt expects. In that one solution is to set the QT_QUICK_BACKEND in "software" making the rendering do it Qt Quick 2D Renderer:
os.environ["QT_QUICK_BACKEND"] = "software"
app = QGuiApplication(sys.argv)
For more information read Scene Graph Adaptations.

Categories