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 -
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@vishnucool220 A simplest way would be to keep a
Q_INVOKABLEfunction on C++ side whose class will be exposed through acontextPropertyto QML. Then you will just need to call this function on button click. To identify which button was pressed you can assign a uniqueobjectNameto 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 ? -
@vishnucool220 A simplest way would be to keep a
Q_INVOKABLEfunction on C++ side whose class will be exposed through acontextPropertyto QML. Then you will just need to call this function on button click. To identify which button was pressed you can assign a uniqueobjectNameto 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 constructorTCPCommunicationPort::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
-
@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 constructorTCPCommunicationPort::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
@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
@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.qmlimport 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) } } } -
@p3c0 Bit and Byte at the QML side will look like:
Bit.qmlimport 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) } } } -
@vishnucool220 So why don't you put that code (which sends 48 bytes data) and call from QML as said earlier ?
@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.