`main.qml` loaded only after the execution of a function called after
-
Hello,
I cross compiled Qt5.14.2 for my raspberry pi 4 and I am trying to create a Qt Quick application
so this is what mymail.cpp
file looks likeinclude <QGuiApplication> #include <QQmlApplicationEngine> #include<QDebug> #include <QQmlEngine> #include<QQmlContext> #include"contacteur.h" #include"capteur.h" #include<QApplication> #include <QtWidgets> #include <QQuickView> #include <QtQml> #include<QTimer> #include<QObject> #include<cstdlib> int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QScopedPointer<Contacteur>contacteur (new Contacteur); QApplication app(argc, argv); QQmlApplicationEngine engine; Capteur capteur; qmlRegisterType<Capteur>("capteur", 1, 0, "Capteur"); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; qDebug()<<"avant l'exution de la fct frein=" <<capteur.getFrein(); capteur.changer_etat(); qDebug()<<"apres l'exution de la fct frein="<< capteur.getFrein(); engine.rootContext()->setContextProperty("contacteur" ,contacteur.data()); return app.exec(); }
I have created a new item with c++ class called Capteur and integrated it to QML.
I am working on interfacing C++ class with the QML so for that I created and application called 'changer_etat()' this fuction containes asleep
fonction fromQThread
and changes one of the attributes off this classcan someone please explain to me why is my
main.qml
loaded only after the execution ofcapteur.changer_etat()
ends knowing that in themain.cpp
the load function is on top of thechanger_etat
function?
Thank you for helpingthis is what my
capteur.h
looks like#ifndef CAPTEUR_H #define CAPTEUR_H #include <QMainWindow> #include <QObject> #include <QWidget> #include<QTimer> class Capteur : public QMainWindow { Q_OBJECT Q_PROPERTY(int frein READ getFrein WRITE setFrein NOTIFY freinChanged) public: explicit Capteur(QWidget *parent = nullptr); int getFrein(); void changer_etat(); private: int m_frein; QTimer *timerFrein; private slots : void onTimeoutfrein ();/ signals: void freinChanged(int); public slots: void setFrein(int T); }; #endif // CAPTEUR_H
this is what my
capteur.cpp
looks like#include "capteur.h" #include<QDebug> #include<cstdlib> #include<QThread> Capteur::Capteur(QWidget *parent) : QMainWindow(parent) { timerFrein =new QTimer (this); timerFrein->setTimerType(Qt::PreciseTimer); connect (timerFrein,SIGNAL(timeout()),this,SLOT(onTimeoutfrein())); timerFrein->start(3000); m_frein=1; } void Capteur::setFrein(int t) { m_frein=t; emit freinChanged(t); } int Capteur::getFrein() { return m_frein; } void Capteur::changer_etat() { QThread::msleep(6000); if (getFrein()==0) { setFrein(1); } else setFrein(0); } void Capteur::onTimeoutfrein() { }
and this is the part of my
main.qml
where I try to interface between both qml and C++Window { id: root visible: true width: 1024 height: 600 title: qsTr("Dashboard") color: "black" Capteur{ id:valeur_capteurs } Rectangle{ id:rect_frein_main x: 555 y: 184 width: 39 height: 24 color: "#00000000" // transparent opacity: 1.0 // frein à main levé Image { id: frein_main width: rect_frein_main.width height: rect_frein_main.height anchors.centerIn: rect_frein_main source: "images/b8.png" } states: [ State { name: "frein_main_levé" when :(valeur_capteurs.frein == 1) PropertyChanges {target: rect_frein_main; opacity:1.0} }, State { name: "frein_main_bas" when :(valeur_capteurs.frein == 0) PropertyChanges {target: rect_frein_main ; opacity:0.0 } }] } }
It has been a while that I am trying to make it work and to see that qml and c++ are interacting, I also tryed to change the value of the attribut in the slot which is connected to the signal timeout of the timer but couldn't work .
If you know please tell me what am I doing wrong?
-
Why do you say that
main.qml
is loaded afterchanger_etat()
? How have you established it? I don't see how, from this code, you could reach such conclusion.In general, UI is shown after you call
app.exec()
and the event loop gets started. That might give an impression of things being executed out of order, but I fail to see how it applies to your case here.BTW. You are creating
Capteur
object twice: one (unused) in C++ and one (used) in QML. These 2 objects are completely separate and will contain different values. You callchanger_etat()
on object which you do not use in QML. -
@amina said in `main.qml` loaded only after the execution of a function called after:
QThread::msleep(6000);
In
changer_etat
there isQThread::msleep(6000);
in the beggining I set it 1000 so just 1 s and I said that I will see the difference when executing the code because after this 1s in qml the opacity of the rectangle rect_frein_main has to change from 1.0 to 0.0 if every thing works fine , but no I didn't see any difference so I started to increase the sleep time .. I put it 6000 so 6s and after that I noticed that my application toked more time to show up.
I added some qdebug inchanger_etat()
and inmain .cpp
before and after calling this function and I noticed that my application shows up only after all these qdebug..Thank you for clarifying that, I will try to remove one of the two object maybe this is causing this problem
-
QThread::msleep(6000);
you run this in main thread, so it will block your entire application for 6 seconds. -
If you want to delay some action, use
QTimer::singleShot()
instead. -
Thank you so much ! I am new to Qt
I also tried this and I didn't now why my counter was incremented 2 times every time out ! now that you clarified that I had 2 objects everything make sense !Thank you
int counter=0; void Capteur::onTimeoutfrein() { counter++; qDebug() <<"time is up"<<counter;/ if (getFrein()==0) { setFrein(1); qDebug() <<"le frein à main est levé" << getFrein(); } else {setFrein(0); qDebug() <<"le frein à main est bas" << getFrein(); } }