Results 1 to 8 of 8

Thread: modify a QML Text from C++

  1. #1
    Join Date
    Jan 2016
    Posts
    81
    Thanks
    31
    Qt products
    Qt5
    Platforms
    Windows

    Default modify a QML Text from C++

    Hi,
    I see data in application output of Qt Creator, but I can not bind this data to text control.
    Please guide me.
    Thanks

    main.cpp:
    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. QApplication app(argc, argv);
    4.  
    5. QQmlApplicationEngine engine;
    6. engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    7.  
    8. MySerialPort iSerialPort;
    9.  
    10. QThread * iTH = new QThread;
    11. iSerialPort.moveToThread(iTH);
    12. iSerialPort.openSerialPort();
    13. iTH->start();
    14.  
    15. return app.exec();
    16. }
    To copy to clipboard, switch view to plain text mode 


    myserialport.cpp:
    Qt Code:
    1. void MySerialPort::readData()
    2. {
    3. QByteArray data = serial->readAll();
    4.  
    5. qDebug() << data;
    6.  
    7. QQmlEngine engine;
    8. QQmlComponent component(&engine, QUrl("qrc:MyItem.qml"));
    9.  
    10. QObject *object = component.create();
    11.  
    12. object->setProperty("text1Text",data);
    13.  
    14. }
    To copy to clipboard, switch view to plain text mode 

    MyItem.qml:
    Qt Code:
    1. import QtQuick 2.0
    2. import QtQuick.Controls 1.2
    3.  
    4. Item {
    5. id: item1
    6. width: 400
    7. height: 400
    8. property alias text1Text: text1.text
    9.  
    10. Text {
    11. id: text1
    12. width: 400
    13. height: 29
    14. color: "red"
    15. text: "This text should change..."
    16. font.pixelSize: 12
    17. }
    18.  
    19. }
    To copy to clipboard, switch view to plain text mode 

    main.qml:
    Qt Code:
    1. import QtQuick 2.3
    2. import QtQuick.Controls 1.2
    3. import QtQuick 2.3
    4.  
    5. ApplicationWindow {
    6. visible: true
    7. width: 640
    8. height: 480
    9. title: qsTr("Hello World")
    10.  
    11. MyItem{
    12.  
    13. }
    14. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: modify a QML Text from C++

    MySerialPort::readData() runs in a worker thread, it can't instantiate UI elements.

    The cleanest way would be to have a model for the strings and use a Repeater in your main.qml to create MyItem instances for each model entry.

    The model would need a slot that takes a string and appends it to its data.

    You would then connect this slot to a signal in your serial port class which is emitted when it has received a new string.

    Cheers,
    _

  3. The following user says thank you to anda_skoa for this useful post:

    neda (13th February 2016)

  4. #3
    Join Date
    Jan 2016
    Posts
    81
    Thanks
    31
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: modify a QML Text from C++

    Quote Originally Posted by anda_skoa View Post
    MySerialPort::readData() runs in a worker thread, it can't instantiate UI elements.

    The cleanest way would be to have a model for the strings and use a Repeater in your main.qml to create MyItem instances for each model entry.

    The model would need a slot that takes a string and appends it to its data.

    You would then connect this slot to a signal in your serial port class which is emitted when it has received a new string.

    Cheers,
    _
    Thanks for your reply.
    Please guide me with simple code.

    I change my code but I don't see any change to text control.
    main.cpp:
    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. QApplication app(argc, argv);
    4.  
    5. QQmlApplicationEngine engine;
    6. engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    7.  
    8. MySerialPort iSerialPort;
    9. QThread* thread = new QThread(app);
    10. iSerialPort.moveToThread(thread);
    11. thread->start();
    12. iSerialPort.myText= engine.rootObjects().at(0)->findChild<QObject*>("text1Text");
    13. iSerialPort.openSerialPort();
    14.  
    15. return app.exec();
    16. }
    To copy to clipboard, switch view to plain text mode 

    serialport.cpp:
    Qt Code:
    1. void MySerialPort::readData()
    2. {
    3. QByteArray data = serial->readAll();
    4.  
    5. qDebug() << data;
    6.  
    7.  
    8. myText->setProperty("text", data);
    9. }
    To copy to clipboard, switch view to plain text mode 

    myserialport.h
    Qt Code:
    1. #ifndef MYSERIALPORT_H
    2. #define MYSERIALPORT_H
    3. #include <QtSerialPort/QtSerialPort>
    4. #include <QObject>
    5. #include <QApplication>
    6. #include <QQmlApplicationEngine>
    7.  
    8. class MySerialPort: public QSerialPort
    9. {
    10. Q_OBJECT
    11. public:
    12. MySerialPort();
    13. QObject *myText;
    14.  
    15. public slots:
    16. void openSerialPort();
    17. void closeSerialPort();
    18.  
    19. void writeData(const QByteArray &data);
    20. void readData();
    21.  
    22. void handleError(QSerialPort::SerialPortError error);
    23.  
    24. private:
    25. void showStatusMessage(const QString &message);
    26.  
    27. QSerialPort *serial;
    28.  
    29. };
    30.  
    31. #endif // MYSERIALPORT_H
    To copy to clipboard, switch view to plain text mode 

    main.qml:
    Qt Code:
    1. ApplicationWindow {
    2. visible: true
    3. width: 640
    4. height: 480
    5. title: qsTr("Hello World")
    6.  
    7.  
    8. Text {
    9. id: text1Text
    10. objectName: text1Text
    11. width: 400
    12. height: 29
    13. color: "red"
    14. text: "This text should change..."
    15. font.pixelSize: 12
    16. }
    17.  
    18. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by neda; 14th February 2016 at 10:58.

  5. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: modify a QML Text from C++

    That still tries to have the thread interact with the GUI, i.e. you still need the mediator object.

    But if you only want to show a single text that is updated with the newest data, then this can be done with a simple property.

    So

    1) Add a signal to MySerialPort that emits the data in readData()

    2) Create a QObject derived class that has a matching slot which updates a QString property, something like this
    Qt Code:
    1. class SerialData : public QObject
    2. {
    3. Q_OBJECT
    4. Q_PROPERTY(QString text READ text NOTIFY textChanged)
    5.  
    6. public slots:
    7. void setText(const QString &text)
    8. {
    9. if (text == m_text) return;
    10. m_text = text;
    11. emit textChanged();
    12. }
    13.  
    14. signals:
    15. void textChanged();
    16.  
    17. private:
    18. QString m_text;
    19. };
    To copy to clipboard, switch view to plain text mode 

    3) Set an instance of that as a context property on the QQmlEngine's rootContext

    4) Connect the serial port signal to the slot

    5) Use the "text" property in QML as the value of the Text element

    Cheers,
    _

  6. The following user says thank you to anda_skoa for this useful post:

    neda (15th February 2016)

  7. #5
    Join Date
    Jan 2016
    Posts
    81
    Thanks
    31
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: modify a QML Text from C++

    My problem is solved.
    Thanks

    main.cpp:
    Qt Code:
    1. #include <QApplication>
    2. #include <QQmlApplicationEngine>
    3. #include <myserialport.h>
    4. #include <QQmlContext>
    5.  
    6. int main(int argc, char *argv[])
    7. {
    8. QApplication app(argc, argv);
    9.  
    10. QQmlApplicationEngine engine;
    11. engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    12.  
    13. MyDisplay myDisplay;
    14. myDisplay.setText("neda");
    15. engine.rootContext()->setContextProperty("myDisplay", &myDisplay);
    16.  
    17. MySerialPort iSerialPort;
    18. iSerialPort.setDisplay(&myDisplay);
    19. iSerialPort.openSerialPort();
    20.  
    21. return app.exec();
    22. }
    To copy to clipboard, switch view to plain text mode 

    mydisplay.h:
    Qt Code:
    1. #include <QObject>
    2.  
    3. #ifndef MYDISPLAY_H
    4. #define MYDISPLAY_H
    5.  
    6. class MyDisplay : public QObject
    7. {
    8. Q_OBJECT
    9. Q_PROPERTY(QString newText READ getText WRITE setText NOTIFY textChanged)
    10.  
    11. public:
    12. MyDisplay();
    13.  
    14. MyDisplay(QString);
    15.  
    16. Q_INVOKABLE QString getText() const;
    17. public slots:
    18. void setText(QString text);
    19.  
    20. signals:
    21. void textChanged(QString);
    22.  
    23. private:
    24. QString newText;
    25. };
    26.  
    27. #endif // MYDISPLAY_H
    To copy to clipboard, switch view to plain text mode 

    mydisplay.cpp:
    Qt Code:
    1. #include "mydisplay.h"
    2. #include "qstring.h"
    3. MyDisplay::MyDisplay()
    4. {
    5. newText = "";
    6. }
    7.  
    8. MyDisplay::MyDisplay(QString text)
    9. {
    10. newText = text;
    11. }
    12.  
    13. QString MyDisplay::getText() const
    14. {
    15. return newText;
    16. }
    17.  
    18. void MyDisplay::setText(QString text)
    19. {
    20. if (text != newText)
    21. {
    22. newText = text;
    23. emit textChanged(text);
    24. }
    25. }
    To copy to clipboard, switch view to plain text mode 

    serialport.cpp:
    Qt Code:
    1. void MySerialPort::readData()
    2. {
    3.  
    4. QByteArray data = serial->readAll();
    5.  
    6.  
    7. qDebug() << data;
    8.  
    9. QString dataString=data;
    10.  
    11. myDisplay->setText(dataString);
    12. }
    13.  
    14. void MySerialPort::setDisplay(MyDisplay * m_display)
    15. {
    16. myDisplay = m_display;
    17. }
    To copy to clipboard, switch view to plain text mode 

    main.qml:
    Qt Code:
    1. ApplicationWindow {
    2. visible: true
    3. width: 640
    4. height: 480
    5. title: qsTr("Hello World")
    6.  
    7. Text {
    8. id: text1Text
    9. //objectName: text1Text
    10. width: 400
    11. height: 29
    12. color: "red"
    13. text: myDisplay.newText
    14. font.pixelSize: 12
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 

    myserialport.h
    Qt Code:
    1. class MySerialPort: public QSerialPort
    2. {
    3. Q_OBJECT
    4. public:
    5. MySerialPort();
    6.  
    7. public slots:
    8. void openSerialPort();
    9. void closeSerialPort();
    10. void setDisplay(MyDisplay * m_display);
    11. void writeData(const QByteArray &data);
    12. void readData();
    13.  
    14. void handleError(QSerialPort::SerialPortError error);
    15.  
    16. private:
    17. void showStatusMessage(const QString &message);
    18. MyDisplay * myDisplay;
    19. QSerialPort *serial;
    20.  
    21. };
    To copy to clipboard, switch view to plain text mode 
    Last edited by neda; 15th February 2016 at 12:49.

  8. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: modify a QML Text from C++

    Quote Originally Posted by neda View Post
    My problem is solved.
    Thanks
    I am surprised that this works.

    In any case you should not call MyDisplay::setText() from the secondary thread, at least not without proper locking.
    See my original suggestion of using a signal/slot connection.

    Cheers,
    _

  9. #7
    Join Date
    Jan 2016
    Posts
    81
    Thanks
    31
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: modify a QML Text from C++

    > I am surprised that this works.

    Why? Which part of the code is illogical?

    > In any case you should not call MyDisplay::setText()
    Why?

    > from the secondary thread
    secondary thread? I did not use thread.

    > at least not without proper locking.

    Please guide me, I do not know about proper locking.

    > See my original suggestion of using a signal/slot connection.

    > 1) Add a signal to MySerialPort that emits the data in readData()

    Qt Code:
    1. connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this,
    2. SLOT(handleError(QSerialPort::SerialPortError)));
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. MySerialPort::MySerialPort()
    2. {
    3. serial = new QSerialPort(this);
    4.  
    5. connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
    6. connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this,
    7. SLOT(handleError(QSerialPort::SerialPortError)));
    8.  
    9. //connect(socket, SIGNAL(setText(QString)), this, SLOT(readData()));
    10.  
    11. }
    To copy to clipboard, switch view to plain text mode 

    > 2) Create a QObject derived class that has a matching slot which updates a QString property

    mydisplay.h:
    Qt Code:
    1. #include <QObject>
    2.  
    3. #ifndef MYDISPLAY_H
    4. #define MYDISPLAY_H
    5.  
    6. class MyDisplay : public QObject
    7. {
    8. Q_OBJECT
    9. Q_PROPERTY(QString newText READ getText WRITE setText NOTIFY textChanged)
    10.  
    11. public:
    12. MyDisplay();
    13.  
    14. MyDisplay(QString);
    15.  
    16. Q_INVOKABLE QString getText() const;
    17.  
    18. public slots:
    19. void setText(QString text);
    20.  
    21. signals:
    22. void textChanged(QString);
    23.  
    24. private:
    25. QString newText;
    26. };
    27.  
    28. #endif // MYDISPLAY_H
    To copy to clipboard, switch view to plain text mode 

    > Set an instance of that as a context property on the QQmlEngine's rootContext

    Qt Code:
    1. engine.rootContext()->setContextProperty("myDisplay", &myDisplay);
    To copy to clipboard, switch view to plain text mode 

    > 5) Use the "text" property in QML as the value of the Text element

    Qt Code:
    1. Text {
    2. id: text1Text
    3. width: 400
    4. height: 29
    5. color: "red"
    6. text: myDisplay.newText
    7. font.pixelSize: 12
    8. }
    To copy to clipboard, switch view to plain text mode 

    I am new in Qt, please guide me to write better code.
    Thank you for your kindness.

  10. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: modify a QML Text from C++

    Quote Originally Posted by neda View Post
    > I am surprised that this works.
    Why? Which part of the code is illogical?
    You load the QML file before setting the context property but the QML code accesses the context property.
    I would have expect that to cause the QML file to fail loading.

    Usually one would set the context property before loading.

    Quote Originally Posted by neda View Post
    > In any case you should not call MyDisplay::setText()
    Why?
    It is OK now, I didn't see you had removed the usage of QThread.

    Quote Originally Posted by neda View Post
    > from the secondary thread
    secondary thread? I did not use thread.
    Right, you had thread usage earlier, didn't see that this changed.

    That also makes the signal/slot approach unnecessary.

    Since you are not using threading anymore you could even add the property to the MySerialPort class and set its instance as the context property.

    Cheers,
    _

  11. The following user says thank you to anda_skoa for this useful post:

    neda (17th February 2016)

Similar Threads

  1. Replies: 1
    Last Post: 11th May 2014, 09:29
  2. Replies: 6
    Last Post: 3rd August 2012, 07:48
  3. Replies: 1
    Last Post: 24th April 2010, 16:31
  4. How to modify the content of text file
    By grsandeep85 in forum Qt Programming
    Replies: 3
    Last Post: 31st July 2009, 11:23
  5. how to modify the text of node in xml docment?
    By GChen in forum Qt Programming
    Replies: 5
    Last Post: 26th February 2009, 11:48

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.