Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to exit void QIODevice::readyRead() function ? Is this function also interrupt?



  • Hello everyone,

    I am reading my data with serial.readall function. In mainwindow function, I am printing my data with qdebug. I get my data properly, no problem, but in order to return to mainwindow function, I need to pass the mouse over the button. How do I get out of this function(QIODevice::readyRead()) without doing this. Thank you all.


  • Lifetime Qt Champion

    @Mucahit I don't understand the problem. Can you rephrase?
    To exit a function/method you simply do a return;



  • When my program is working in the main function, when the data comes from the serial port, it calls the readyread function automatically. But to exit this function, I need to pass it over the mouse button. How can I get it out of this function when it has finished receiving data? More precisely, how can I get the mouse to leave without passing over any button?

    The event I want is this: When the data comes from the serial port, it will automatically go and get that data and return it to my screen and print it. Since I do not want to do any operation in the interrupt function, I want it to be done after exiting that function. I used the atEnd() function but it didn't work

    I'm sorry for my bad english.


  • Lifetime Qt Champion

    @Mucahit I still don't get what readyRead has to do with mouse cursor. If you want to do something after readyRead finishes you could use QTimer for example. But since I don't really understand what you're describing I don't know...



  • Because after the readyread function works, it doesn't shut down unless I move the mouse.Readyread function gets stuck. I want to leave this function when the last data import is finished. The atEnd() function should work for this but it didn't work.


  • Lifetime Qt Champion

    @Mucahit Can you show your code? Especially slot connected to readyRead().



  • Of course,

    QByteArray data;
    QByteArray totaldata;

    void QIODevice::readyRead()
    {
    data=serial.readAll();
    totaldata=totaldata+data;
    }

    void MainWindow::paintEvent(QPaintEvent *)
    {
    qDebug()<<totaldata; // I want to print the data I receive here because I will draw pies based on the data I received
    }


  • Lifetime Qt Champion

    @Mucahit said in How to exit void QIODevice::readyRead() function ? Is this function also interrupt?:

    I want to print the data I receive here because I will draw pies based on the data I received

    And what is the problem?



  • Does not print this data without moving the mouse. So I can't get out of this readyread function and switch to paintevent.


  • Moderators

    @Mucahit said in How to exit void QIODevice::readyRead() function ? Is this function also interrupt?:

    paintEvent is not being called, just because totalData changed ...

    try calling update() it will schedule a paint event call at the next possible time.

    void QIODevice::readyRead()
    {
    data=serial.readAll();
    totaldata=totaldata+data;
    update();
    }
    


  • Yes that's exactly what i want but the update function didn't work.

    I had to use the update function like this:

    void QIODevice::readyRead()
    {
    data=serial.readAll();
    totaldata=totaldata+data;
    QMainWindow main;
    main.update();
    }



  • @Mucahit said in How to exit void QIODevice::readyRead() function ? Is this function also interrupt?:

    QMainWindow main;
    main.update();

    You really can't do this. That is a local variable, it has nothing to do with your main window. This is basic C++ stuff.


  • Moderators

    @Mucahit said in How to exit void QIODevice::readyRead() function ? Is this function also interrupt?:

    void QIODevice::readyRead()
    {
    data=serial.readAll();
    totaldata=totaldata+data;
    QMainWindow main;
    main.update();
    }

    this should do nothing, that creates a new main window and destroys it immediately, you don't event show() it.

    You have to signal your mainwinow instance to update, do that via a custom signal, emitted from your iodevice


  • Lifetime Qt Champion

    @Mucahit said in How to exit void QIODevice::readyRead() function ? Is this function also interrupt?:

    QMainWindow main;

    ?
    You create a NEW QMainWindow instance here!
    Why don't you simply try to actually draw anything in your paintEvent?



  • I dont know how to do i am new in qt and c ++. I do not know how to renew my previously found chart pie in my main window with any data I read from the serial port. When the application is first opened, the chart pie is painted with 50 percent, but it will be 70 percent when any value comes from the serial port. Sorry for bothering you.


  • Lifetime Qt Champion

    @Mucahit You can redraw completely based on updated data. If paintEvent() is called the previously drawn content is deleted.



  • But I want to do this outside the readyread function when all the data reading is finished, so that it does not hinder my data reading speed. How can I do that ?


  • Lifetime Qt Champion

    @Mucahit First: you do it already outside of readyRead()! update() does not call paintEvent() directly, it only puts the event in the event queue. Second: do you have a protocol or how do you know when the reading is done? If you have a protocall when you can use a bool variable which is set to true when all data was read (and call update()) and use this variable inside paintEvent() to check whether you need to paint or not.



  • I understood very well what you said. Yes i have a protocol but i can't trigger paintevent.


  • Lifetime Qt Champion

    @Mucahit said in How to exit void QIODevice::readyRead() function ? Is this function also interrupt?:

    but i can't trigger paintevent

    Why not? You just need to store received data, set a bool flag and call update.



  • Now my code is below:

    QByteArray data;
    QByteArray totaldata;

    void QIODevice::readyRead()
    {
    data=serial.readAll();
    totaldata=totaldata+data;
    if(totaldata=="xFe/xD3/xFD")
    {
    MainWindow main;
    main.update();
    // or main.repaint();
    }
    }
    void MainWindow::paintEvent(QPaintEvent *)
    {
    qDebug()<<totaldata; // I want to print the data I receive here because I will draw pies based on the data I received
    }

    I see the data i read from the serial port in the output of this code, right? But i don't see anything. As i said, i can only get my qdebug output when I hover my mouse over the window. It never prints that value on the screen if I don't move it.


  • Lifetime Qt Champion

    @Mucahit Sorry, but this code does not make any sense! You already were told that creating a temporary QMainWindow instance and calling update() on it is simply wrong! You need to call update on your widget where you want to paint.
    I suggest you take time to check some paintEvent examples, like https://doc.qt.io/qt-5/qtwidgets-widgets-analogclock-example.html



  • Thank you sir, i know how i can make a watch. All i want is to call paintevent in readyread function and i couldn't solve this problem. All i want is a line of code not an article, i can't. Please can you share how to call paintevent in function code to me ?


  • Lifetime Qt Champion

    @Mucahit said in How to exit void QIODevice::readyRead() function ? Is this function also interrupt?:

    Please can you share how to call paintevent in function code to me ?

    This already was explained: you do NOT call paintEvent directly, Qt framework does it for you when the widget needs to be repainted. You call update() to trigger a paint event when needed.
    "All i want is a line of code not an article" - so, you want a magical line of code without spending time to learn how to paint? You already spent one day in forum. You could have read the example in this time to understand how it works...



  • Thank you. You tell me the way to call the update function is wrong. I wanted to learn the truth. It is not difficult to read an article, I do not understand what you mean in the article i am reading. I think i need to study and learn more about qt and c ++. Thanks for all the help.


  • Lifetime Qt Champion

    @Mucahit said in How to exit void QIODevice::readyRead() function ? Is this function also interrupt?:

    You tell me the way to call the update function is wrong

    Yes, because you call update() on a temporary MainWindow instance which is completely unrelated to your actual main window instance.

    void QIODevice::readyRead()
    {
    data=serial.readAll();
    totaldata=totaldata+data;
    if(totaldata=="xFe/xD3/xFD")
    {
        update();
    }
    }
    

    There is one thing you need to change I think: you should not try to paint directly on main window. Create a custom widget (subclass QWidget) and override paintEvent() there (this is what is done in the example). Before calling update() on it you will need to pass the data to it:

    void QIODevice::readyRead()
    {
    data=serial.readAll();
    totaldata=totaldata+data;
    if(totaldata=="xFe/xD3/xFD")
    {
        ui->myPaintWidget->setData(totaldata); // myPaintWidget is your custom widget
        ui->myPaintWidget->update();
    }
    }
    

    Put this custom widget where you want to paint.

    "I think i need to study and learn more about qt and c ++" - this would help.



  • Thank you very much for the detailed explanation I think I understand my mistake. I have one last step left. I am getting this error : use of undeclared identifier 'update'. The same goes for ui->. I think I made a serious mistake in the class structure.

    ---------mainwindow.h :

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QPainter>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    private:
    Ui::MainWindow *ui;
    protected:
    void paintEvent(QPaintEvent *);

    };
    #endif // MAINWINDOW_H

    --------------main cpp :

    #include "mainwindow.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
    }

    -------------mainwindow.cpp :

    #include "mainwindow.h"
    #include "ui_mainwindow.h"

    #include<QSerialPort>
    #include<QtSerialPort/QSerialPort>

    QSerialPort serial;
    #include<QDebug>

    QByteArray data;
    QByteArray totaldata;

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    serial.setPortName("ttyS0");
    serial.setBaudRate(QSerialPort::Baud115200);
    serial.setDataBits(QSerialPort::Data8);
    serial.setParity(QSerialPort::NoParity);
    serial.setStopBits(QSerialPort::OneStop);
    serial.setFlowControl(QSerialPort::NoFlowControl);
    serial.open(QIODevice::ReadWrite);
    
    if(serial.isOpen()==true)
    {
    ui->label_23->setText("serial opened");
    }
    else
    {
    ui->label_23->setText("serial closed");
    }
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    serial.close();
    }
    void QIODevice::readyRead()
    {
    data=serial.readAll();
    totaldata=totaldata+data;

    if(totaldata=="xFe/xD3/xFD")
    {
    qDebug()<<totaldata;
     ui->   // now i am getting this error
         update(); // same error
    }
    

    }
    void MainWindow::paintEvent(QPaintEvent *)
    {
    if(totaldata=="xFe/xD3/xFD")
    {
    qDebug()<<totaldata;

    QPainter chart1(this);
        QRectF size1=QRectF(200,169,this->width()-720,this->width()-720);
        chart1.setBrush(Qt::blue);
        chart1.drawPie(size1,0,126*16);
        chart1.setBrush(Qt::red);
        chart1.drawPie(size1,126*16,234*16);
    
        QPainter chart2(this);
        QRectF size2=QRectF(360,169,this->width()-720,this->width()-720);
        chart2.setBrush(Qt::blue);
        chart2.drawPie(size2,0,180*16);
        chart2.setBrush(Qt::red);
        chart2.drawPie(size2,180*16,180*16);
    
        QPainter chart3(this);
        QRectF size3=QRectF(500,169,this->width()-720,this->width()-720);
        chart3.setBrush(Qt::blue);
        chart3.drawPie(size3,0,288*16);
        chart3.setBrush(Qt::red);
        chart3.drawPie(size3,288*16,72*16);
    
    }
    else
    {
    QPainter chart1(this);
        QRectF size1=QRectF(200,169,this->width()-720,this->width()-720);
        chart1.setBrush(Qt::blue);
        chart1.drawPie(size1,0,0*16);
        chart1.setBrush(Qt::red);
        chart1.drawPie(size1,0*16,360*16);
    
        QPainter chart2(this);
        QRectF size2=QRectF(360,169,this->width()-720,this->width()-720);
        chart2.setBrush(Qt::blue);
        chart2.drawPie(size2,0,0*16);
        chart2.setBrush(Qt::red);
        chart2.drawPie(size2,0*16,360*16);
    
        QPainter chart3(this);
        QRectF size3=QRectF(500,169,this->width()-720,this->width()-720);
        chart3.setBrush(Qt::blue);
        chart3.drawPie(size3,0,0*16);
        chart3.setBrush(Qt::red);
        chart3.drawPie(size3,0*16,360*16);
    
        QPainter rectangle(this);
        rectangle.setBrush(Qt::blue);
        rectangle.drawRect(QRect(200,264,10,10));
        rectangle.setBrush(Qt::blue);
        rectangle.drawRect(QRect(360,264,10,10));
        rectangle.setBrush(Qt::blue);
        rectangle.drawRect(QRect(505,264,10,10));
     }
    

    }


  • Lifetime Qt Champion

    @Mucahit said in How to exit void QIODevice::readyRead() function ? Is this function also interrupt?:

    void QIODevice::readyRead()

    What is this?!

    You need a slot in MainWindow which you connect to readyRead signal from your serial port:

    void MainWindow::readyRead()
    {
    ...
    }
    
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        connect(&serial, &QSerialPort::readyRead, this, &MainWindow::readyRead);
    ...
    }
    

    Please read https://doc.qt.io/qt-5/signalsandslots.html



  • Oh !!! thank you so much. It turns out that I searched my mistake in many different places. Do you want me to mark the problem as resolved or delete the title or change the title? Because my question is very different with the question I asked. Thank you very much again.I made you struggle.


  • Lifetime Qt Champion

    @Mucahit Up to you. But if it is solved now you should mark it as solved.



  • Of course it is solved. Thank you very much for your efforts.


Log in to reply