Event filter in QML or How to detect the multiple mouse events in a smart way



  • I have to send 48 Bytes of Data to controller via Qtcpsocket. I have represented each **Bit ** in a Byte as a Button in QML. So whenever the user clicks the button, I have to set the Corresponding **Bit **to true/false and immediately send the entire 48 Bytes of data.
    I have so many buttons(Bits) in so many QML files. How to detect which button has been pressed and immediately set the corresponding Bit? How to get the Object in qml ?
    What i have done is emitting a signal in the Bit when button is pressed. Now confused how to pass it to the backend c++ on to the sockets because then i would have so many signals. I feel like it’s not a proper way to do. Any smart / better solution or similar example would be really helpful.Thanks


  • Moderators

    @vishnucool220 A simplest way would be to keep a Q_INVOKABLE function on C++ side whose class will be exposed through a contextProperty to QML. Then you will just need to call this function on button click. To identify which button was pressed you can assign a unique objectName to each button which you can pass to this function along with the 48 bytes of data.
    BTW, how are you storing that 48 bytes of data on QML side ?



  • @p3c0 Thanks for the reply. I really don't know how to handle it in QML side. What i have done in c++ side is:

    
     struct ControlRegister2
    {
        bool bit1:1;
        bool bit2:1;
        bool bit3:1;
        bool bit4:1;
        bool bit5:1;
        bool bit6:1;
        bool bit7:1;
        bool bit8:1;
    }; 
    class TCPCommunicationPort : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString ipaddress READ ipaddress WRITE setipaddress NOTIFY ipaddressChanged)
    
        Q_PROPERTY(qint16 port READ port WRITE setPort)
    public:
        explicit TCPCommunicationPort(QObject *parent = 0);
        ~TCPCommunicationPort();
    
    
        qint16 port() const;
        QString ipaddress() const;
        Q_INVOKABLE bool isConnected(void) const;
    private:
        QTcpServer *m_tcpServer;
        QTcpSocket *m_tcpSocket;
        bool m_bOnline;
        QByteArray  m_sendBuffer;
        QString m_ipaddress;
        qint16 m_port;
        ControlRegister2 *contrlreg;
    signals:
        void ipaddressChanged();
        void newRawData(QString data);
    public slots:
        void sendRawData(QString data);
        void setipaddress(const QString &ipAddress);
        void setPort(qint16 port);
        bool startListening();
        void processNewConnection();
        void stopTCPServer();
        void socketStateChanged(QAbstractSocket::SocketState state);
        void socketReadyRead();
    };
    
    

    QByteArray m_sendBuffer;// member variable
    //In the constructor

    TCPCommunicationPort::TCPCommunicationPort(QObject *parent) : QObject(parent),m_tcpSocket(NULL)
    {
       qDebug()<<"TCPCommunicationPort::TCPCommunicationPort";
       m_tcpServer = new QTcpServer(this);
       m_sendBuffer.reserve(48);
       connect(m_tcpServer,SIGNAL(newConnection()),this,SLOT(processNewConnection()));
    
       contrlreg = new ControlRegister2();
       contrlreg->bit1=false;
       contrlreg->bit2=false;
       contrlreg->bit3=false;
       contrlreg->bit4=false;
       contrlreg->bit5=false;
       contrlreg->bit6=true;
       contrlreg->bit7=false;
       contrlreg->bit8=false;
    }
    

    //How the data of 48Bytes is sent. This is just an example modifying only one Byte out of 48Bytes and keeping remaining as zero.

            qint8 a=0;
            for(int i=0;i<13;++i)
            {
                m_sendBuffer.append(a);//first 13Bytes are zero (just an example)
            }
            QByteArray registerbyte;
            registerbyte[0]= *(char *)contrlreg;//size of controlreg is just 1 byte
            m_sendBuffer.append(registerbyte);
            for(int i=1;i<35;++i)
            {
                m_sendBuffer.append(a);
            }
    //Here we send the message
            if(m_tcpSocket->state()== QAbstractSocket::ConnectedState)
            {
                m_tcpSocket->write(m_sendBuffer);
                qDebug()<<"send data"<<m_sendBuffer.toHex();
            }
    
    

    I have no idea how to handle the data at QML side. I thought of handling the data at C++ side and somehow connect the signals from QML to solts in C++. Am I wrong? If so please suggest me the right way to do it.Thanks a lot


  • Moderators

    @vishnucool220 So you have that 48 bytes of data already on C++ side ?



  • @p3c0 Not everything I am just tried with one byte. If you can suggest me where to handle the data that would be really helpful.Thanks


  • Moderators

    @vishnucool220 So why don't you put that code (which sends 48 bytes data) and call from QML as said earlier ?



  • @p3c0 Bit and Byte at the QML side will look like:
    Bit.qml

    import QtQuick 2.0
    Rectangle {
        id: bitwithDescription
    
        width: parent.width
        height: festoDesign.bitHeight
    
        property bool active: false
        property alias setbitText: bitText.text
        property alias setDescription: bitDescription.text
        signal bitStatus(bool active)
        FestoDesign{id:festoDesign}
    
        Rectangle{
            id: bit
            height: parent.height
            width: festoDesign.bitWidth
            anchors.left: parent.left
            anchors.leftMargin: festoDesign.contentLeftMargin
            anchors.topMargin:  festoDesign.contentTopMargin
            border.width: 2
            radius: festoDesign.buttonRadius
            color: active ? festoDesign.bitColorEnabled: festoDesign.bitcolorDisable
    
            MouseArea{
                anchors.fill: parent
                onClicked: {
                    active= !active
                    bitStatus(active)
                }
                Text {
                    id: bitText
                    text: qsTr("bit")
                    anchors.centerIn: parent
                    font.family: festoDesign.fontFamilyRegular
                    font.pixelSize: festoDesign.fontSizeSmall
                    color: festoDesign.colorButtonText
                }
            }
        }
        Rectangle{
            id:description
            height: parent.height
            radius: festoDesign.buttonRadius
            width: parent.width
            anchors.left: bit.right
            anchors.leftMargin: festoDesign.bitdescriptorGap
    
            Text {
                id: bitDescription
                text: qsTr("Description")
                anchors.topMargin: festoDesign.bitdescriptorTopMargin
                anchors.leftMargin: festoDesign.bitdescriptorLeftMargin
                anchors.fill: parent
                anchors.centerIn: parent
                font.family: festoDesign.fontFamilyRegular
                font.pixelSize: festoDesign.fontSizeSmall
                color: festoDesign.colorButtonText
            }
        }
    }
    

    Register.qml or Byte

    import QtQuick 2.0
    import QtQuick.Window 2.0
    Rectangle {
        id: register
        anchors.fill: parent
        FestoDesign{id:festoDesign}
        property alias setBit1Caption: bit1.setbitText
        property alias setBit2Caption: bit2.setbitText
        property alias setBit3Caption: bit3.setbitText
        property alias setBit4Caption: bit4.setbitText
        property alias setBit5Caption: bit5.setbitText
        property alias setBit6Caption: bit6.setbitText
        property alias setBit7Caption: bit7.setbitText
        property alias setBit8Caption: bit8.setbitText
    
        property alias setBit1Description: bit1.setDescription
        property alias setBit2Description: bit2.setDescription
        property alias setBit3Description: bit3.setDescription
        property alias setBit4Description: bit4.setDescription
        property alias setBit5Description: bit5.setDescription
        property alias setBit6Description: bit6.setDescription
        property alias setBit7Description: bit7.setDescription
        property alias setBit8Description: bit8.setDescription
    
        property alias bit1active: bit1.active
        property alias bit2active: bit2.active
        property alias bit3active: bit3.active
        property alias bit4active: bit4.active
        property alias bit5active: bit5.active
        property alias bit6active: bit6.active
        property alias bit7active: bit7.active
        property alias bit8active: bit8.active
    
        property alias setTitle: title.text
    
    //    Column{
    //        spacing: 1340
            Text{
                id:title
                anchors.horizontalCenter: register.horizontalCenter
                anchors.top: parent.top
                anchors.topMargin: festoDesign.contentTopMargin
                text: "Title"
                font.pixelSize : festoDesign.fontSizeLarge
                font.family: festoDesign.fontFamilyRegular
            }
    
            Bit{
                id:bit1
                anchors.top: title.bottom
                anchors.left: parent.left
                anchors.topMargin: festoDesign.contentTopMargin
                setbitText: "setbitText"
                setDescription: qsTr("setDescription")
                onBitStatus:{
                 console.log("bit1 status:" + active)
                }
            }
            Bit{
                id:bit2
                anchors.top: bit1.bottom
                anchors.left: parent.left
                anchors.topMargin: festoDesign.bitTobitdistance
                setbitText: "setbitText"
                setDescription: qsTr("setDescription")
                onBitStatus:{
                 console.log("bit2 status:" + active)
                }
            }
            Bit{
                id:bit3
                anchors.top: bit2.bottom
                anchors.left: parent.left
                anchors.topMargin: festoDesign.bitTobitdistance
                setbitText: "setbitText"
                setDescription: qsTr("setDescription")
                onBitStatus:{
                 console.log("bit3 status:" + active)
                }
            }
            Bit{
                id:bit4
                anchors.top: bit3.bottom
                anchors.left: parent.left
                anchors.topMargin: festoDesign.bitTobitdistance
                setbitText: "setbitText"
                setDescription: qsTr("setDescription")
                onBitStatus:{
                 console.log("bit4 status:" + active)
                }
            }
            Bit{
                id:bit5
                anchors.top: bit4.bottom
                anchors.left: parent.left
                anchors.topMargin: festoDesign.bitTobitdistance
                setbitText: "setbitText"
                setDescription: qsTr("setDescription")
                onBitStatus:{
                 console.log("bit5 status:" + active)
                }
            }
            Bit{
                id:bit6
                anchors.top: bit5.bottom
                anchors.left: parent.left
                anchors.topMargin: festoDesign.bitTobitdistance
                setbitText: "setbitText"
                setDescription: qsTr("setDescription")
                onBitStatus:{
                 console.log("bit6 status:" + active)
                }
            }
            Bit{
                id:bit7
                anchors.top: bit6.bottom
                anchors.left: parent.left
                anchors.topMargin: festoDesign.bitTobitdistance
                setbitText: "setbitText"
                setDescription: qsTr("setDescription")
                onBitStatus:{
                 console.log("bit7 status:" + active)
                }
            }
            Bit{
                id:bit8
                anchors.top: bit7.bottom
                anchors.left: parent.left
                anchors.topMargin: festoDesign.bitTobitdistance
                setbitText: "setbitText"
                setDescription: qsTr("setDescription")
                onBitStatus:{
                 console.log("bit8 status:" + active)
                }
            }
    }
    

  • Moderators

    @vishnucool220 As said you can call a C++ function when Bit pressed. Call it from onClicked event handler.
    I strongly suggest you to go through this link for how to get access to C++ objects and its functions from QML.



  • @p3c0 Where exactly i should put that code? As I asked earlier how should i know which button is pressed ?If you see my code I did with a signal but in that case i would need so many signals which is not a smart way to do. I am thinking of Bit masking .For example (sudo code)

    OnClicked(Object sender)
    {
    if(sender == "BIT1")
       {
    BYTE1 |= 0x01; // AND operation 
    BYTE2 &= 0xFE; // OR operation 
       }
    

    But don't know how to get that object and implement in qml.



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.