Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. GUI does not have time to update?

GUI does not have time to update?

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 5 Posters 4.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    maratk1n
    wrote on last edited by maratk1n
    #1

    I open the valve and immediately update the paint buttons:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
    //***
        emergency = new EmergencyResetOfPressure();
        connect(emergency, SIGNAL(openValveSignal(int)), this, SLOT(openValve(int)));
        connect(emergency, SIGNAL(closeValveSignal(int)), this, SLOT(closeValve(int)));
        //emergency->start();
        emergency->moveToThread(emergency);
        connect(this, SIGNAL(destroyed(QObject*)), emergency, SLOT(quit()));
    
        connect(ui->emergencyButton, SIGNAL(clicked(bool)), this, SLOT(emergencyRelease()));
    //***
    }
    void MainWindow::emergencyRelease()  
    {
        if (!emergency->isRun)
        {
            emergency->start();
            //emit emergencyReleaseSig();
        }
        else
        {
            emergency->quit(); //How do I stop the flow? Ideally, abort "run" and start the stop algorithm
        }
    
    }
    void MainWindow::openValve(int id)
    {
        //QString style = QString(DEFAULT_STYLE_BUTTON) + QString(DEFAULT_BACKGROUND_BUTTON);
        //valveButton[id]->setStyleSheet(style);
    
        QString str = "Valve №" + QString::number(id+1);
        valveButton[id]->setEnabled(false);
        if (valve->open(id)) {
            if (manualModeState)
                valveButton[id]->setEnabled(true);
            //valveButton[id]->setPalette(QPalette(Qt::green));
            //valveButton[id]->setStyleSheet(VALVE_OPEN_COLOR);
            QString style = QString(DEFAULT_STYLE_BUTTON) + QString(DEFAULT_BACKGROUND_BUTTON);
            valveButton[id]->setStyleSheet(style);
            ui->mainLabel->setText(str + " opened! :)");
        }
        else {
            if (manualModeState)
                valveButton[id]->setEnabled(true);
            ui->mainLabel->setText("Cant open " + str);
            remoteStatus(0);
        }
    }
    void MainWindow::closeValve(int id)
    {
        QString str = "Valve №" + QString::number(id+1);
        valveButton[id]->setEnabled(false);
        if (valve->close(id)) {
            if (manualModeState)
                valveButton[id]->setEnabled(true);
            //valveButton[id]->setPalette(style()->standardPalette());
            valveButton[id]->setStyleSheet("");
            ui->mainLabel->setText(str + " closed! :)");
        }
        else {
            if (manualModeState)
                valveButton[id]->setEnabled(true);
            ui->mainLabel->setText("Cant close " + str);
            remoteStatus(0);
        }
    }
    
    EmergencyResetOfPressure::EmergencyResetOfPressure(QObject *parent) : QThread(parent)
    {
    }
    
    EmergencyResetOfPressure::~EmergencyResetOfPressure()
    {
    }
    
    void EmergencyResetOfPressure::run()
    {
        isRun = true;
        for (int i = 0; i<7; i++)
        {
            msleep(200);
            emit openValveSignal(i);
        }
        for (int i = 0; i<7; i++)
        {
            msleep(200);
            emit closeValveSignal(i);
        }
    }
    

    If done without sleep/msleep, the buttons are not painted over. Why?
    P.S. valve->close/valve->open takes some time (60-70ms), because there is communication on the port. But is not the if() expected to wait for the response of the function?

    J.HilkJ 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      What you are doing is blocking the event loop that's why you don't see any GUI update. You are basically chaining blocking methods that takes long time to run several times in a row.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      3
      • thamT Offline
        thamT Offline
        tham
        wrote on last edited by tham
        #3

        I think SGaist provide correct answer, setStyleSheet is slow. Just some tips,

        1 : you have memory leak

        emergency = new EmergencyResetOfPressure;
        

        It should be

        emergency = new EmergencyResetOfPressure(this);
        

        Please find a great book of c++ and study how to handle resource by parent and child mechanism of Qt, this could make your life easier if you want to develop things with Qt.

        2 : this line is weird

        emergency->moveToThread(emergency);
        

        it loooks weird to move the QThread into the same QThread, unless I do not know what would happen under this case

        M 1 Reply Last reply
        0
        • thamT tham

          I think SGaist provide correct answer, setStyleSheet is slow. Just some tips,

          1 : you have memory leak

          emergency = new EmergencyResetOfPressure;
          

          It should be

          emergency = new EmergencyResetOfPressure(this);
          

          Please find a great book of c++ and study how to handle resource by parent and child mechanism of Qt, this could make your life easier if you want to develop things with Qt.

          2 : this line is weird

          emergency->moveToThread(emergency);
          

          it loooks weird to move the QThread into the same QThread, unless I do not know what would happen under this case

          M Offline
          M Offline
          maratk1n
          wrote on last edited by maratk1n
          #4

          @tham said in GUI does not have time to update?:

          setStyleSheet is slow

          So... How can I update the appearance of the buttons if I want to switch the valves as quickly as possible?
          ui->mainLabel->setText(str + " opened! :)"); also does not work.
          The code should not be consistently executed? I do not understand anything ...

          @tham said in GUI does not have time to update?:

          emergency->moveToThread(emergency);

          it loooks weird to move the QThread into the same QThread

          As I understand it, the object is created in the main thread, so you need to reassign it to another thread

          jsulmJ thamT 2 Replies Last reply
          0
          • M maratk1n

            @tham said in GUI does not have time to update?:

            setStyleSheet is slow

            So... How can I update the appearance of the buttons if I want to switch the valves as quickly as possible?
            ui->mainLabel->setText(str + " opened! :)"); also does not work.
            The code should not be consistently executed? I do not understand anything ...

            @tham said in GUI does not have time to update?:

            emergency->moveToThread(emergency);

            it loooks weird to move the QThread into the same QThread

            As I understand it, the object is created in the main thread, so you need to reassign it to another thread

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @maratk1n "As I understand it, the object is created in the main thread, so you need to reassign it to another thread" - this is wrong.
            A QThread instance maintains a thread - it does not run in the thread it is maintaining.

            "If done without sleep/msleep, the buttons are not painted over. Why?" - @SGaist already explained why. closeValve() and openValve() need long to do their work as you said. While they are busy the Qt event loop is blocked and the UI cannot be updated. If you put thos sleep calls then there is enough time for closeValve() and openValve() to finish and the event loop can then update the UI before closeValve() and openValve() are called again.
            Qt is an event driven framework as most other GUI related frameworks. You should adapt to event driven programming. One of the most important rules: do not block the event loop.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            M 1 Reply Last reply
            1
            • jsulmJ jsulm

              @maratk1n "As I understand it, the object is created in the main thread, so you need to reassign it to another thread" - this is wrong.
              A QThread instance maintains a thread - it does not run in the thread it is maintaining.

              "If done without sleep/msleep, the buttons are not painted over. Why?" - @SGaist already explained why. closeValve() and openValve() need long to do their work as you said. While they are busy the Qt event loop is blocked and the UI cannot be updated. If you put thos sleep calls then there is enough time for closeValve() and openValve() to finish and the event loop can then update the UI before closeValve() and openValve() are called again.
              Qt is an event driven framework as most other GUI related frameworks. You should adapt to event driven programming. One of the most important rules: do not block the event loop.

              M Offline
              M Offline
              maratk1n
              wrote on last edited by
              #6

              @jsulm What is the way out of this situation? Create signals and slots?

              jsulmJ 1 Reply Last reply
              0
              • M maratk1n

                @jsulm What is the way out of this situation? Create signals and slots?

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @maratk1n What I don't understand is: what's the point to call openValveSignal(i) 7 times in a row and in each call update the UI? Look: you call openValveSignal(i) for the first time, it updates the UI, then the second call arrives and updates the UI - who will notice the first UI update if it is IMMEDIATELY overwritten? And so forth... Same for closeValveSignal(i).

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                M 1 Reply Last reply
                0
                • jsulmJ jsulm

                  @maratk1n What I don't understand is: what's the point to call openValveSignal(i) 7 times in a row and in each call update the UI? Look: you call openValveSignal(i) for the first time, it updates the UI, then the second call arrives and updates the UI - who will notice the first UI update if it is IMMEDIATELY overwritten? And so forth... Same for closeValveSignal(i).

                  M Offline
                  M Offline
                  maratk1n
                  wrote on last edited by
                  #8

                  @jsulm These are seven different buttons for seven valves. I want to quickly open all 7 valves and, correspondingly, paint all 7 buttons.

                  jsulmJ 1 Reply Last reply
                  0
                  • M maratk1n

                    @jsulm These are seven different buttons for seven valves. I want to quickly open all 7 valves and, correspondingly, paint all 7 buttons.

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @maratk1n Then you should not block the event loop.
                    As a work around (not really a good solution) you can call http://doc.qt.io/qt-5/qcoreapplication.html#processEvents instead of msleep.

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • M maratk1n

                      @tham said in GUI does not have time to update?:

                      setStyleSheet is slow

                      So... How can I update the appearance of the buttons if I want to switch the valves as quickly as possible?
                      ui->mainLabel->setText(str + " opened! :)"); also does not work.
                      The code should not be consistently executed? I do not understand anything ...

                      @tham said in GUI does not have time to update?:

                      emergency->moveToThread(emergency);

                      it loooks weird to move the QThread into the same QThread

                      As I understand it, the object is created in the main thread, so you need to reassign it to another thread

                      thamT Offline
                      thamT Offline
                      tham
                      wrote on last edited by tham
                      #10

                      @maratk1n said in GUI does not have time to update?:

                      So... How can I update the appearance of the buttons if I want to switch the valves as quickly as possible?

                      Maybe you can give setPalette a try first?If this do not work, let us find next solution.

                      @maratk1n said in GUI does not have time to update?:

                      ui->mainLabel->setText(str + " opened! :)"); also does not work.

                      This is weird, maybe your codes have some bugs(like I say, please study a great c++ book, this could save you a lot of headaches, education in university is far from enough), could you reproduce the issues with minimum codes and upload the whole project to somewhere(mega, dropbox, etc)?

                      M 1 Reply Last reply
                      0
                      • thamT tham

                        @maratk1n said in GUI does not have time to update?:

                        So... How can I update the appearance of the buttons if I want to switch the valves as quickly as possible?

                        Maybe you can give setPalette a try first?If this do not work, let us find next solution.

                        @maratk1n said in GUI does not have time to update?:

                        ui->mainLabel->setText(str + " opened! :)"); also does not work.

                        This is weird, maybe your codes have some bugs(like I say, please study a great c++ book, this could save you a lot of headaches, education in university is far from enough), could you reproduce the issues with minimum codes and upload the whole project to somewhere(mega, dropbox, etc)?

                        M Offline
                        M Offline
                        maratk1n
                        wrote on last edited by
                        #11

                        @tham said in GUI does not have time to update?:

                        education in university is far from enough

                        I did not have any programming at the university (now I'm studying in the magistracy for robotics)...

                        @tham said in GUI does not have time to update?:

                        could you reproduce the issues with minimum codes and upload the whole project to somewhere(mega, dropbox, etc)?

                        I can upload anywhere, but this will not work, because communication with the board occurs

                        thamT 1 Reply Last reply
                        0
                        • M maratk1n

                          @tham said in GUI does not have time to update?:

                          education in university is far from enough

                          I did not have any programming at the university (now I'm studying in the magistracy for robotics)...

                          @tham said in GUI does not have time to update?:

                          could you reproduce the issues with minimum codes and upload the whole project to somewhere(mega, dropbox, etc)?

                          I can upload anywhere, but this will not work, because communication with the board occurs

                          thamT Offline
                          thamT Offline
                          tham
                          wrote on last edited by tham
                          #12

                          @maratk1n said in GUI does not have time to update?:

                          I can upload anywhere, but this will not work, because communication with the board occurs

                          What do you mean "communication with the board occurs"? Do you program depend on some specific hardware?

                          "reproduce the issues with minimum codes" == Do not send us your whole project, create a new project, with minimum lines of codes which could reproduce your issues.

                          If your issues are hardware/os specific, please write down the hardware, os, compiler and Qt version you are using.

                          @maratk1n said in GUI does not have time to update?:

                          I did not have any programming at the university (now I'm studying in the magistracy for robotics)...

                          Then I think study a great book of c++ could help you even more, Programming -- Principles and Practice Using C++ (Second Edition). This book is design for beginners of programming and c++

                          1 Reply Last reply
                          0
                          • M maratk1n

                            I open the valve and immediately update the paint buttons:

                            MainWindow::MainWindow(QWidget *parent) :
                                QMainWindow(parent),
                                ui(new Ui::MainWindow)
                            {
                            //***
                                emergency = new EmergencyResetOfPressure();
                                connect(emergency, SIGNAL(openValveSignal(int)), this, SLOT(openValve(int)));
                                connect(emergency, SIGNAL(closeValveSignal(int)), this, SLOT(closeValve(int)));
                                //emergency->start();
                                emergency->moveToThread(emergency);
                                connect(this, SIGNAL(destroyed(QObject*)), emergency, SLOT(quit()));
                            
                                connect(ui->emergencyButton, SIGNAL(clicked(bool)), this, SLOT(emergencyRelease()));
                            //***
                            }
                            void MainWindow::emergencyRelease()  
                            {
                                if (!emergency->isRun)
                                {
                                    emergency->start();
                                    //emit emergencyReleaseSig();
                                }
                                else
                                {
                                    emergency->quit(); //How do I stop the flow? Ideally, abort "run" and start the stop algorithm
                                }
                            
                            }
                            void MainWindow::openValve(int id)
                            {
                                //QString style = QString(DEFAULT_STYLE_BUTTON) + QString(DEFAULT_BACKGROUND_BUTTON);
                                //valveButton[id]->setStyleSheet(style);
                            
                                QString str = "Valve №" + QString::number(id+1);
                                valveButton[id]->setEnabled(false);
                                if (valve->open(id)) {
                                    if (manualModeState)
                                        valveButton[id]->setEnabled(true);
                                    //valveButton[id]->setPalette(QPalette(Qt::green));
                                    //valveButton[id]->setStyleSheet(VALVE_OPEN_COLOR);
                                    QString style = QString(DEFAULT_STYLE_BUTTON) + QString(DEFAULT_BACKGROUND_BUTTON);
                                    valveButton[id]->setStyleSheet(style);
                                    ui->mainLabel->setText(str + " opened! :)");
                                }
                                else {
                                    if (manualModeState)
                                        valveButton[id]->setEnabled(true);
                                    ui->mainLabel->setText("Cant open " + str);
                                    remoteStatus(0);
                                }
                            }
                            void MainWindow::closeValve(int id)
                            {
                                QString str = "Valve №" + QString::number(id+1);
                                valveButton[id]->setEnabled(false);
                                if (valve->close(id)) {
                                    if (manualModeState)
                                        valveButton[id]->setEnabled(true);
                                    //valveButton[id]->setPalette(style()->standardPalette());
                                    valveButton[id]->setStyleSheet("");
                                    ui->mainLabel->setText(str + " closed! :)");
                                }
                                else {
                                    if (manualModeState)
                                        valveButton[id]->setEnabled(true);
                                    ui->mainLabel->setText("Cant close " + str);
                                    remoteStatus(0);
                                }
                            }
                            
                            EmergencyResetOfPressure::EmergencyResetOfPressure(QObject *parent) : QThread(parent)
                            {
                            }
                            
                            EmergencyResetOfPressure::~EmergencyResetOfPressure()
                            {
                            }
                            
                            void EmergencyResetOfPressure::run()
                            {
                                isRun = true;
                                for (int i = 0; i<7; i++)
                                {
                                    msleep(200);
                                    emit openValveSignal(i);
                                }
                                for (int i = 0; i<7; i++)
                                {
                                    msleep(200);
                                    emit closeValveSignal(i);
                                }
                            }
                            

                            If done without sleep/msleep, the buttons are not painted over. Why?
                            P.S. valve->close/valve->open takes some time (60-70ms), because there is communication on the port. But is not the if() expected to wait for the response of the function?

                            J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by J.Hilk
                            #13

                            @maratk1n Hi, to simply fix your problem, without going deeper into the issue, I believe this can be solved in a few easy steps.

                            First you need a new SIGNAL

                            signals:
                                void valveIsOpen(int id);
                            

                            That is emited when your open function is finished. Than you need a slot to update your buttons:

                            void updateValveButtons(int id){
                                QString str = "Valve №" + QString::number(id+1);
                                valveButton[id]->setEnabled(true);
                                     QString style = QString(DEFAULT_STYLE_BUTTON) + QString(DEFAULT_BACKGROUND_BUTTON);
                                     valveButton[id]->setStyleSheet(style);
                                     ui->mainLabel->setText(str+ " opened! :)");
                            }
                            

                            than connect the SIGNAL/SLOT :

                            connect(valve, SIGNAL(valveIsOpen(int), this, SLOT(updateValveButtons(int),Qt::QueuedConnection);
                            

                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved