Access problem of QML objects to nestet custom properties in PySide 6
-
Hello guys. This is my first forum post here so sorry if I make some mistakes in the problem description.
I'm developing an app with PySide backed and QML fronted. On the python side, I have my main.py where creating root context property of my AppCore class. Appcore.py stores custom properties of other classes for handling specific tasks. For example, ProjectMenager holds information about project properties and methods related to service-specific tasks. On QML side I have a lot of custom QML Objects that use those nested properties.
My problem is that invoking a function from ProjectMenager class to create project returns an error:
AttributeError: 'PySide6.QtGui.QGuiApplication' object has no attribute 'child_event'
The above exception was the direct cause of the following exception:
SystemError: PyEval_EvalFrameEx returned a result with an error set
file:///C:/Users/BardKrzysztof/Desktop/TensorflowAPI/Pyside6_App/dialogs/NewProjectDialog.qml:34:
Error: PyEval_EvalFrameEx returned a result with an error setWhat's more, property binding in QML Text Object, won't get property value of that PtojectMenager, despite of having it in a variable (check several times)
Could somebody say where is problem and how to resolve it?
# This Python file uses the following encoding: utf-8 import sys from PySide6 import * from __feature__ import snake_case from __feature__ import true_property from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine, qmlRegisterType from appcore import * app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() opencv = OpencvImageProvider() prMang = ProjectMenager() paintHan = PaintHandler() appCore = Appcore(projectMenager=prMang, opencvMenager=opencv, paintHandler=paintHan) engine.root_context().set_context_property('appCore', appCore) engine.quit.connect(app.quit) engine.load('main.qml') sys.exit(app.exec())
# This Python file uses the following encoding: utf-8 from PySide6.QtCore import Slot, Property, QObject, Signal from PySide6.QtQml import QmlElement, QmlSingleton import os from projectMenager import ProjectMenager from opencvImageProvider import OpencvImageProvider from paintHandler import PaintHandler class Appcore(QObject): projectMenagerChanged = Signal() opencvImageProviderChanged = Signal() paintHandlerChanged = Signal() def __init__(self, projectMenager: ProjectMenager, opencvMenager: OpencvImageProvider, paintHandler: PaintHandler): super(Appcore, self).__init__() self.projectMenager = projectMenager self.opencvMenager = opencvMenager self.paintHandler = paintHandler print(self.projectMenager) """ Property setters and getters """ def get_project_menager(self): return self.projectMenager def get_opnecv_menager(self): return self.opencvMenager def get_paint_handler(self): return self.paintHandler """ Properties exposed to QML """ prMeg = Property(ProjectMenager, get_project_menager, notify=projectMenagerChanged) openCV = Property(OpencvImageProvider, get_opnecv_menager, notify=opencvImageProviderChanged) paintHan = Property(PaintHandler, get_paint_handler, notify=paintHandlerChanged)
# This Python file uses the following encoding: utf-8 from PySide6.QtCore import Slot, Property, Signal, QObject import os class ProjectMenager(QObject): projectNameChanged = Signal() projectDescriptionChanged = Signal() projectLocationChanged = Signal() projectDateChanged = Signal() projectPathChanged = Signal() def __init__(self): super().__init__() self.projectName = None self.projectDescription = None self.projectLocation = None self.projectDate = None self.path = None @Slot(str, str, str, str) def create_new_project(self, name, desc, loc, date): self.projectName = name self.projectDescription = desc self.projectLocation = loc self.projectDate = date self.path = os.getcwd() print("Otrzymałem dane") ... def get_project_name(self): return self.projectName def get_project_des(self): return self.projectDescription def get_project_loc(self): return self.projectLocation def get_project_date(self): return self.projectDate def get_project_path(self): return self.path """ Properties """ project_name = Property(str, get_project_name, notify=projectNameChanged) project_desc = Property(str, get_project_des, notify=projectDescriptionChanged) project_loc = Property(str, get_project_loc, notify=projectLocationChanged) project_date = Property(str, get_project_date, notify=projectDateChanged) project_path = Property(str, get_project_path, notify=projectPathChanged)
part of NewProjectDialog.qml
import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Dialogs //import QtGraphicalEffects 1.0 import "../GUI/Colors.js" as Colors Item{ id: control ... function acc(){ console.log("fcn acc") appCore.prMeg.create_new_project(newProjectDialog.projectName, newProjectDialog.projectDescription, newProjectDialog.projectLocation, newProjectDialog.projectDate) console.log("New project passed") // console.log(projectMenager.project_name, projectMenager.project_path) control.clear() newProjectDialog.close() } width: 300 height: 440 Dialog{ id: newProjectDialog property string projectName: projectNameInput.text property string projectDescription: projectDescriptionInput.text property string projectLocation: projectLocationInput.text property string projectDate: projectDateInput.text ... }
property biding that isn't working
Text { text: appCore.prMeg.project_name anchors.bottom: parent.bottom anchors.margins: parent.height/10 }
-
So, I think that I found a solution.
First of all, that error above was caused because of my __feature__ imports in the main.py file.
In order to that property binding in Text QML Object, it was needed to emit a python signal with string and it worked.