Search code examples
c++qtqmlconnection

couldn't interface C++ and Qml (connections)


I am working on a project on my raspberry pi 4 that uses GPIO.

I cross compiled Qt 5.14.2 and I created a QtQuick application

so I am working with the wiringPi library, I followed this tutorial https://www.youtube.com/watch?v=HxNHlhv74tA and I created a GPIO class that contains a private attribute m_value (it didn't work also when putting my attribute public).

so I created an interrupt (rising and falling) and every time that an interrupt is detected I changed the value of my attribute m_value and a signal was emitted (I check with qdebug that everything is working fine ) and based on the value of the attribute I wanted to change the opacity of a rectangle and it didn't work.

Connections
   {
       target: input3

       onInputChanged:
       {
           if(input3.m_value ==0 )
               rectInput3.opacity = 0.0
           else
               rectInput3.opacity = 1.0
       }
   }

Am I doing something wrong?

this is what my main.cpp looks like

#include "gpio.h"
#include<QDebug>
int impulsion=0;
static void isrInput3();
static GPIO input3(3, GPIO_INPUT, isrInput3);
static void isrInput3()
{
    impulsion ++;
    input3.isrCallback();
    qDebug()<<"the number of pulses"<<impulsion<<"le nombre de tour est "<<impulsion/8;
    qDebug()<<"m_value "<<input3.readPin();
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
   QQmlContext* ctx = engine.rootContext();
     ctx->setContextProperty("input3", &input3);
  const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
    return app.exec();
}
}

this is what my GPIO.h looks like

class GPIO : public QObject
{
    Q_OBJECT
public:
    explicit GPIO(int pin, int type, void (*isrInput)(void) = nullptr, QObject *parent = nullptr);
    void isrCallback();
    int readPin();
private:
    int m_value;
signals:
    void inputChanged(int value);

};
#endif // GPIO_H

and this is my GPIO.cpp

GPIO::GPIO(int pin, int type, void (*isrInput)(void), QObject *parent) : QObject(parent)
{
    wiringPiSetup();
    m_pin = pin;
       switch(type)
    {
        case GPIO_INPUT:
        {
            pinMode(m_pin, INPUT);
            wiringPiISR(m_pin, INT_EDGE_BOTH, isrInput);
        } break;

        case GPIO_OUTPUT:
        {
            pinMode(m_pin, OUTPUT);

        } break;
         }
}

void GPIO::isrCallback()
{ if (digitalRead(m_pin)== 1)
        m_value=1;
    else m_value=0;
    emit inputChanged(m_value);
    qDebug()<<"signal emitted";

}
int GPIO::readPin()
{
    return digitalRead(m_pin);
}

Solution

  • When you emitted a signal to Qml side, you can reach the emitted parameter by its name. If you change the code like:

    Connections
           {
               target: input3
        
               onInputChanged:
               {
                   if(value ==0 )
                       rectInput3.opacity = 0.0
                   else
                       rectInput3.opacity = 1.0
               }
           }
    

    Now it should work. You may also check inside:

               onInputChanged:
               {
                  console.log(value)
               }
    

    The tutorial you are following also reached the variable by this way.