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 -
@vishnucool220 A simplest way would be to keep a
Q_INVOKABLE
function on C++ side whose class will be exposed through acontextProperty
to QML. Then you will just need to call this function on button click. To identify which button was pressed you can assign a uniqueobjectName
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 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 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 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.