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. Question about show() hide()
Forum Updated to NodeBB v4.3 + New Features

Question about show() hide()

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 7 Posters 1.3k Views 4 Watching
  • 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.
  • Q Offline
    Q Offline
    Quiccz
    wrote on last edited by
    #1

    I would like to display 30 pictures on the screen, and then show another 30 pictures after a 10-second delay, repeating this cycle.

    // if parent2 showing now.
    // change to parent1.
    for(int i = 0; i < 30; i++)
    {
        picWidget1[i].show();
    }
    parent1.show();
    parent2.hide();
    for(int i = 0; i < 30; i++)
    {
        picWidget2[i].hide();
    }
    
    

    30 pics show in parent1, 30 pics show in parent2.

    My understanding is that after I call show, it enters the showEvent. Then, when I call hide, it enters the hideEvent. In the next event loop, it starts processing the paintEvent of pic_widgets1, and after all the painting is done, it proceeds to handle the paintEvent of parent1. Then, parent2 is hidden, and since pic_widgets2 is its child, the hide of pic_widgets2 is actually meaningless. According to this logic, the first 30 images should be displayed only after the paintEvent of parent1 is completed. Moreover, they should all be already painted and ready to be displayed simultaneously. However, in reality, sometimes they are not displayed simultaneously, and some images are slower to appear. This conflicts with my understanding.

    JonBJ sierdzioS 2 Replies Last reply
    0
    • S Offline
      S Offline
      SimonSchroeder
      wrote on last edited by
      #16

      There is no reason to call show() or hide() on your pictures. Just show and hide the parent widgets.

      Here is my try to explain why with the order show() -> showAll() the pictures can appear one after the other. You are correct that the basic understanding of signals and slots is that events are queued inside the event loop. However, the default connection is an AutoConnection. If both sender and receiver are inside the same thread this defaults to a DirectConnection. This means that the event loop is skipped. This is especially true for repaint() which will immediately draw the widget. Because you are doing this in a loop (and PicWidget::paintEvent() has a delay) one picture must appear after the other. The general advice is to never use repaint(), but use update() instead. This can significantly increase performance. update() will gather several calls first if they appear quickly after another and only then call repaint(). I am not entirely sure about the underlying mechanism of update() or if the event loop is involved. show() itself will call update() (or something similar) internally. This means that several calls to show() also are first gathered.

      With the order showAll() -> show() nothing will happen when calling show() for each picture because their parent widget is not visible. They are basically marked as visible and that's it. I don't think repaint() will do anything here as well. Only when show() is called on the parent will all the pictures be drawn. As this is a single paintEvent on the parent widget it will not be interrupted (drawing all of its children) before it can be shown on the screen (Qt does not paint on the screen directly, but uses double buffering, so that only after all draw commands of a single update() call are finished will they show on the screen). Just as I said in the beginning: Don't ever call show/hide on your PicWidgets. Just call it on the parent which will manage all the rest.

      @Quiccz said in Question about show() hide():

      I found my program bug. so close it

      This is up to you. If you found a particular answer useful, click the three dots of that answer and mark the post as solved. Otherwise post your solution for others to find and select that one as the correct answer. (Somewhere there is also an option to mark it as solved without selecting an answer.)

      Q 1 Reply Last reply
      3
      • Q Quiccz

        I would like to display 30 pictures on the screen, and then show another 30 pictures after a 10-second delay, repeating this cycle.

        // if parent2 showing now.
        // change to parent1.
        for(int i = 0; i < 30; i++)
        {
            picWidget1[i].show();
        }
        parent1.show();
        parent2.hide();
        for(int i = 0; i < 30; i++)
        {
            picWidget2[i].hide();
        }
        
        

        30 pics show in parent1, 30 pics show in parent2.

        My understanding is that after I call show, it enters the showEvent. Then, when I call hide, it enters the hideEvent. In the next event loop, it starts processing the paintEvent of pic_widgets1, and after all the painting is done, it proceeds to handle the paintEvent of parent1. Then, parent2 is hidden, and since pic_widgets2 is its child, the hide of pic_widgets2 is actually meaningless. According to this logic, the first 30 images should be displayed only after the paintEvent of parent1 is completed. Moreover, they should all be already painted and ready to be displayed simultaneously. However, in reality, sometimes they are not displayed simultaneously, and some images are slower to appear. This conflicts with my understanding.

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #2

        @Quiccz
        I don't think calling show/hide() enters/raises those events at the time you call them. It merely marks a widget as to be shown or hidden. Events don't get raised until that actually happens (from the event loop).

        Normally you do not need to show/hide child widgets: showing/hiding a parent widget takes child widgets with it.

        When showing one of a number of widgets (parent1 or parent2) you might like to use QStackedWidget instead of manually managing show/hide()s yourself.

        I don't think this has anything to do with any time it might take to e.g. load an image, I don't think that happens when you call show/hide(). It only happens when the image is actually shown, I think. I don't know if there is a way/call to make it so the images are all preloaded so that they show any faster when called for, there might be.

        Q 1 Reply Last reply
        3
        • Q Quiccz

          I would like to display 30 pictures on the screen, and then show another 30 pictures after a 10-second delay, repeating this cycle.

          // if parent2 showing now.
          // change to parent1.
          for(int i = 0; i < 30; i++)
          {
              picWidget1[i].show();
          }
          parent1.show();
          parent2.hide();
          for(int i = 0; i < 30; i++)
          {
              picWidget2[i].hide();
          }
          
          

          30 pics show in parent1, 30 pics show in parent2.

          My understanding is that after I call show, it enters the showEvent. Then, when I call hide, it enters the hideEvent. In the next event loop, it starts processing the paintEvent of pic_widgets1, and after all the painting is done, it proceeds to handle the paintEvent of parent1. Then, parent2 is hidden, and since pic_widgets2 is its child, the hide of pic_widgets2 is actually meaningless. According to this logic, the first 30 images should be displayed only after the paintEvent of parent1 is completed. Moreover, they should all be already painted and ready to be displayed simultaneously. However, in reality, sometimes they are not displayed simultaneously, and some images are slower to appear. This conflicts with my understanding.

          sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #3

          @Quiccz There is no need for your loops. If you hide a parent, all children get hidden, too.

          (Z(:^

          1 Reply Last reply
          1
          • JonBJ JonB

            @Quiccz
            I don't think calling show/hide() enters/raises those events at the time you call them. It merely marks a widget as to be shown or hidden. Events don't get raised until that actually happens (from the event loop).

            Normally you do not need to show/hide child widgets: showing/hiding a parent widget takes child widgets with it.

            When showing one of a number of widgets (parent1 or parent2) you might like to use QStackedWidget instead of manually managing show/hide()s yourself.

            I don't think this has anything to do with any time it might take to e.g. load an image, I don't think that happens when you call show/hide(). It only happens when the image is actually shown, I think. I don't know if there is a way/call to make it so the images are all preloaded so that they show any faster when called for, there might be.

            Q Offline
            Q Offline
            Quiccz
            wrote on last edited by Quiccz
            #4

            @JonB I write a demo.

            #ifndef PICWIDGET_H
            #define PICWIDGET_H
            
            #include <QMainWindow>
            #include <QLabel>
            class PicWidget : public QWidget
            {
                Q_OBJECT
            
            public:
                PicWidget(QWidget *parent = nullptr);
                ~PicWidget();
                void setPic(QString file);
                void paintEvent(QPaintEvent* event) override;
                void showEvent(QShowEvent* event) override;
                void hideEvent(QHideEvent* event) override;
            
            
            private:
                QLabel* m_label;
            };
            #endif // PICWIDGET_H
            
            
            #include "picwidget.h"
            
            PicWidget::PicWidget(QWidget *parent)
                : QWidget(parent)
            {
            }
            
            PicWidget::~PicWidget()
            {
            }
            
            void PicWidget::showEvent(QShowEvent* event)
            {
                QWidget::showEvent(event);
                qDebug() << "pic show event";
            }
            
            void PicWidget::paintEvent(QPaintEvent* event)
            {
                QWidget::paintEvent(event);
                qDebug() << "pic paint event";
            }
            
            void PicWidget::hideEvent(QHideEvent* event)
            {
                QWidget::hideEvent(event);
                qDebug() << "pic hide event";
            }
            
            void PicWidget::setPic(QString file)
            {
                m_label = new QLabel(this);
                QImage img = QImage(file);
                m_label->setPixmap(QPixmap::fromImage(img));
                m_label->show();
            }
            
            
            #ifndef PARENTWIDGET_H
            #define PARENTWIDGET_H
            #include <QWidget>
            #include "picwidget.h"
            class ParentWidget : public QWidget
            {
            public:
                ParentWidget(QWidget* parent = nullptr);
                void paintEvent(QPaintEvent* event) override;
                void showEvent(QShowEvent* event) override;
                void hideEvent(QHideEvent* event) override;
                void showAll();
                void hideAll();
            private:
                QVector<PicWidget*> pics;
            };
            
            #endif // PARENTWIDGET_H
            
            
            #include "parentwidget.h"
            
            ParentWidget::ParentWidget(QWidget* parent)
                : QWidget(parent)
            {
                for(int i = 0; i < 1; i++)
                {
                    PicWidget* pic = new PicWidget(this);
                    pic->setPic("D://test.png");
                    pic->setGeometry(i*100, i*100, 100, 100);
                    pics.push_back(pic);
                }
            }
            
            void ParentWidget::showAll()
            {
                for(int i = 0; i < pics.size(); i++)
                {
                    pics[i]->show();
                }
            }
            
            void ParentWidget::hideAll()
            {
                for(int i = 0; i < pics.size(); i++)
                {
                    pics[i]->hide();
                }
            }
            
            void ParentWidget::showEvent(QShowEvent* event)
            {
                QWidget::showEvent(event);
                qDebug() << "parent show event";
            }
            
            void ParentWidget::paintEvent(QPaintEvent* event)
            {
                QWidget::paintEvent(event);
                qDebug() << "parent paint event";
            }
            
            void ParentWidget::hideEvent(QHideEvent* event)
            {
                QWidget::hideEvent(event);
                qDebug() << "parent hide event";
            }
            
            
            #include "parentwidget.h"
            
            #include <QApplication>
            #include <QTimer>
            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
                QMainWindow window;
                window.show();
                ParentWidget w1(&window);
                ParentWidget w2(&window);
                w1.setGeometry(0, 0, 300, 300);
                w2.setGeometry(0, 0, 300, 300);
                QTimer::singleShot(3000, [&](){
                    qDebug() << "w1 showall";
                    w1.showAll();
                    qDebug() << "w1 show";
                    w1.show();
                    qDebug() << "w2 hide";
                    w2.hide();
                    qDebug() << "w2 hideall";
                    w2.hideAll();
                    qDebug() << "end1";
            
                });
            
                QTimer::singleShot(6000, [&](){
                    qDebug() << "w2 showall";
                    w2.showAll();
                    qDebug() << "w2 show";
            
                    w2.show();
                    qDebug() << "w1 hide";
            
                    w1.hide();
                    qDebug() << "w1 hideall";
            
                    w1.hideAll();
                    qDebug() << "end2";
            
                });
                return a.exec();
            }
            
            

            Here is output
            5540ea54-a896-44b4-80de-af4b441020fe-image.png

            it seems pic parent paint first then pic paint.

            If i paint 10 pics, and add sleep in pic_paintevent, it will show all pics at same time after 10s.
            77508e41-a471-449f-ada3-3916fe2b9eba-image.png

            if parent show first, it will show all pics at same time after 10s, why?
            04377262-cbd7-4065-9048-b202ddd49146-image.png

            Pl45m4P 1 Reply Last reply
            0
            • Q Quiccz

              @JonB I write a demo.

              #ifndef PICWIDGET_H
              #define PICWIDGET_H
              
              #include <QMainWindow>
              #include <QLabel>
              class PicWidget : public QWidget
              {
                  Q_OBJECT
              
              public:
                  PicWidget(QWidget *parent = nullptr);
                  ~PicWidget();
                  void setPic(QString file);
                  void paintEvent(QPaintEvent* event) override;
                  void showEvent(QShowEvent* event) override;
                  void hideEvent(QHideEvent* event) override;
              
              
              private:
                  QLabel* m_label;
              };
              #endif // PICWIDGET_H
              
              
              #include "picwidget.h"
              
              PicWidget::PicWidget(QWidget *parent)
                  : QWidget(parent)
              {
              }
              
              PicWidget::~PicWidget()
              {
              }
              
              void PicWidget::showEvent(QShowEvent* event)
              {
                  QWidget::showEvent(event);
                  qDebug() << "pic show event";
              }
              
              void PicWidget::paintEvent(QPaintEvent* event)
              {
                  QWidget::paintEvent(event);
                  qDebug() << "pic paint event";
              }
              
              void PicWidget::hideEvent(QHideEvent* event)
              {
                  QWidget::hideEvent(event);
                  qDebug() << "pic hide event";
              }
              
              void PicWidget::setPic(QString file)
              {
                  m_label = new QLabel(this);
                  QImage img = QImage(file);
                  m_label->setPixmap(QPixmap::fromImage(img));
                  m_label->show();
              }
              
              
              #ifndef PARENTWIDGET_H
              #define PARENTWIDGET_H
              #include <QWidget>
              #include "picwidget.h"
              class ParentWidget : public QWidget
              {
              public:
                  ParentWidget(QWidget* parent = nullptr);
                  void paintEvent(QPaintEvent* event) override;
                  void showEvent(QShowEvent* event) override;
                  void hideEvent(QHideEvent* event) override;
                  void showAll();
                  void hideAll();
              private:
                  QVector<PicWidget*> pics;
              };
              
              #endif // PARENTWIDGET_H
              
              
              #include "parentwidget.h"
              
              ParentWidget::ParentWidget(QWidget* parent)
                  : QWidget(parent)
              {
                  for(int i = 0; i < 1; i++)
                  {
                      PicWidget* pic = new PicWidget(this);
                      pic->setPic("D://test.png");
                      pic->setGeometry(i*100, i*100, 100, 100);
                      pics.push_back(pic);
                  }
              }
              
              void ParentWidget::showAll()
              {
                  for(int i = 0; i < pics.size(); i++)
                  {
                      pics[i]->show();
                  }
              }
              
              void ParentWidget::hideAll()
              {
                  for(int i = 0; i < pics.size(); i++)
                  {
                      pics[i]->hide();
                  }
              }
              
              void ParentWidget::showEvent(QShowEvent* event)
              {
                  QWidget::showEvent(event);
                  qDebug() << "parent show event";
              }
              
              void ParentWidget::paintEvent(QPaintEvent* event)
              {
                  QWidget::paintEvent(event);
                  qDebug() << "parent paint event";
              }
              
              void ParentWidget::hideEvent(QHideEvent* event)
              {
                  QWidget::hideEvent(event);
                  qDebug() << "parent hide event";
              }
              
              
              #include "parentwidget.h"
              
              #include <QApplication>
              #include <QTimer>
              int main(int argc, char *argv[])
              {
                  QApplication a(argc, argv);
                  QMainWindow window;
                  window.show();
                  ParentWidget w1(&window);
                  ParentWidget w2(&window);
                  w1.setGeometry(0, 0, 300, 300);
                  w2.setGeometry(0, 0, 300, 300);
                  QTimer::singleShot(3000, [&](){
                      qDebug() << "w1 showall";
                      w1.showAll();
                      qDebug() << "w1 show";
                      w1.show();
                      qDebug() << "w2 hide";
                      w2.hide();
                      qDebug() << "w2 hideall";
                      w2.hideAll();
                      qDebug() << "end1";
              
                  });
              
                  QTimer::singleShot(6000, [&](){
                      qDebug() << "w2 showall";
                      w2.showAll();
                      qDebug() << "w2 show";
              
                      w2.show();
                      qDebug() << "w1 hide";
              
                      w1.hide();
                      qDebug() << "w1 hideall";
              
                      w1.hideAll();
                      qDebug() << "end2";
              
                  });
                  return a.exec();
              }
              
              

              Here is output
              5540ea54-a896-44b4-80de-af4b441020fe-image.png

              it seems pic parent paint first then pic paint.

              If i paint 10 pics, and add sleep in pic_paintevent, it will show all pics at same time after 10s.
              77508e41-a471-449f-ada3-3916fe2b9eba-image.png

              if parent show first, it will show all pics at same time after 10s, why?
              04377262-cbd7-4065-9048-b202ddd49146-image.png

              Pl45m4P Offline
              Pl45m4P Offline
              Pl45m4
              wrote on last edited by
              #5

              @Quiccz said in Question about show() hide():

              If i paint 10 pics, and add sleep in pic_paintevent, it will show all pics at same time after 10s.

              Don't let your GUI thread sleep. It's bad. You won't receive any events then.


              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

              ~E. W. Dijkstra

              Q 1 Reply Last reply
              1
              • Pl45m4P Pl45m4

                @Quiccz said in Question about show() hide():

                If i paint 10 pics, and add sleep in pic_paintevent, it will show all pics at same time after 10s.

                Don't let your GUI thread sleep. It's bad. You won't receive any events then.

                Q Offline
                Q Offline
                Quiccz
                wrote on last edited by Quiccz
                #6

                @Pl45m4 It is just a test, i try to figureout why my pics won't show together in my other project. But my demo show together. i thought it because paint pic need time, so i add sleep for test.
                ebfec6e9-956c-4a3e-8384-733a1a921d54-image.png
                result same.

                I try to add some event between pic paintevent and parent paintevent but failed.

                JonBJ 1 Reply Last reply
                0
                • Q Quiccz

                  @Pl45m4 It is just a test, i try to figureout why my pics won't show together in my other project. But my demo show together. i thought it because paint pic need time, so i add sleep for test.
                  ebfec6e9-956c-4a3e-8384-733a1a921d54-image.png
                  result same.

                  I try to add some event between pic paintevent and parent paintevent but failed.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #7

                  @Quiccz The above will just occupy/block the main thread.

                  Q 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @Quiccz The above will just occupy/block the main thread.

                    Q Offline
                    Q Offline
                    Quiccz
                    wrote on last edited by Quiccz
                    #8

                    @JonB
                    I know it will block the main thread. In another real project of mine, I also displayed multiple sub-widgets one by one, and then showed the parent widget. After that, I hid another parent widget, but the actual display sometimes showed 27 out of 30 images simultaneously, with the remaining three images appearing one by one. However, there were times when all 30 images would display together. I initially thought it was due to the time needed for painting high-resolution images in my paint event, so I used a for loop to simulate this time-consuming process. It takes about 10ms to paint each image. In the demo, even with a 1s delay, it does not result in displaying the images one by one; instead, all images are shown simultaneously after the paint event for each image completes.

                    What I primarily want to know is whether there are any factors that could affect the order of display. I have been unable to identify the issue in my actual project.

                    JoeCFDJ M 2 Replies Last reply
                    0
                    • Q Quiccz

                      @JonB
                      I know it will block the main thread. In another real project of mine, I also displayed multiple sub-widgets one by one, and then showed the parent widget. After that, I hid another parent widget, but the actual display sometimes showed 27 out of 30 images simultaneously, with the remaining three images appearing one by one. However, there were times when all 30 images would display together. I initially thought it was due to the time needed for painting high-resolution images in my paint event, so I used a for loop to simulate this time-consuming process. It takes about 10ms to paint each image. In the demo, even with a 1s delay, it does not result in displaying the images one by one; instead, all images are shown simultaneously after the paint event for each image completes.

                      What I primarily want to know is whether there are any factors that could affect the order of display. I have been unable to identify the issue in my actual project.

                      JoeCFDJ Offline
                      JoeCFDJ Offline
                      JoeCFD
                      wrote on last edited by JoeCFD
                      #9

                      @Quiccz I guess paint events(in event loop) may not come one after another in a big app with a lot of running threads. And threads also access CPU randomly one after another. The main thread has some pause as well. Some other apps in the OS need to access CPU too.

                      1 Reply Last reply
                      0
                      • Q Quiccz

                        @JonB
                        I know it will block the main thread. In another real project of mine, I also displayed multiple sub-widgets one by one, and then showed the parent widget. After that, I hid another parent widget, but the actual display sometimes showed 27 out of 30 images simultaneously, with the remaining three images appearing one by one. However, there were times when all 30 images would display together. I initially thought it was due to the time needed for painting high-resolution images in my paint event, so I used a for loop to simulate this time-consuming process. It takes about 10ms to paint each image. In the demo, even with a 1s delay, it does not result in displaying the images one by one; instead, all images are shown simultaneously after the paint event for each image completes.

                        What I primarily want to know is whether there are any factors that could affect the order of display. I have been unable to identify the issue in my actual project.

                        M Offline
                        M Offline
                        mpergand
                        wrote on last edited by
                        #10

                        @Quiccz
                        Try repaint() right after show()

                        w1.show();
                        w1.repaint();

                        1 Reply Last reply
                        0
                        • Q Offline
                          Q Offline
                          Quiccz
                          wrote on last edited by
                          #11

                          My understanding of the event loop is that, after executing a.exec() in the main function, the program enters the event loop. Other threads can emit messages (such as when a QTimer's time is up), which will place the corresponding functions into the event loop. The event loop acts like a queue, where events are retrieved from the front of the queue and their corresponding functions are executed until each function is completed before moving to the next event.

                          If that's the case, why do we see w1.showall, w1.show, followed by pic show event, then parent show event, and finally w2.hideall and w2.hide? It appears that the show event doesn't enter the event loop but is instead a regular function call because it is invoked before w2.hide within my QTimer function.

                          In this scenario, the reason pic show event comes first is that after calling w1.showall, it realizes that the parent widget (w1) is not yet shown, so it doesn't trigger the show event. After w1 is shown, it doesn't immediately trigger w1's show event. Instead, it needs to iterate through the child widgets and invoke their show event if they are in the shown state.

                          1 Reply Last reply
                          0
                          • Q Offline
                            Q Offline
                            Quiccz
                            wrote on last edited by
                            #12

                            If i let w1 show first and add delay in paintevent and paint 11 pics and add repaint https://streamable.com/r8r0u9
                            6ba53d28-34ea-4ae1-ad9e-b74105523474-image.png
                            8ce4fcea-b465-41db-90ea-04cba83e3f97-image.png
                            6d6c9ba9-9a62-4822-b164-e07b3639d6ee-image.png

                            if i let w1.showall first https://streamable.com/izhzvq
                            198930f8-1f04-4815-a3df-534fec49443e-image.png

                            Pl45m4P 1 Reply Last reply
                            0
                            • Q Quiccz

                              If i let w1 show first and add delay in paintevent and paint 11 pics and add repaint https://streamable.com/r8r0u9
                              6ba53d28-34ea-4ae1-ad9e-b74105523474-image.png
                              8ce4fcea-b465-41db-90ea-04cba83e3f97-image.png
                              6d6c9ba9-9a62-4822-b164-e07b3639d6ee-image.png

                              if i let w1.showall first https://streamable.com/izhzvq
                              198930f8-1f04-4815-a3df-534fec49443e-image.png

                              Pl45m4P Offline
                              Pl45m4P Offline
                              Pl45m4
                              wrote on last edited by
                              #13

                              @Quiccz

                              The reason for this is the parent-child struture.
                              If you show the Parent first and then showAll childs (pics) in a loop, it works as in the first video.

                              If you call showAll first, all pics/childs are queued to be shown, but cant show up because their parent is hidden. When you then show the ParentWidget the queue is emptied and all childs show up without delay.

                              That would be my explanation for this. Could also have other influences


                              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                              ~E. W. Dijkstra

                              Q 1 Reply Last reply
                              0
                              • Pl45m4P Pl45m4

                                @Quiccz

                                The reason for this is the parent-child struture.
                                If you show the Parent first and then showAll childs (pics) in a loop, it works as in the first video.

                                If you call showAll first, all pics/childs are queued to be shown, but cant show up because their parent is hidden. When you then show the ParentWidget the queue is emptied and all childs show up without delay.

                                That would be my explanation for this. Could also have other influences

                                Q Offline
                                Q Offline
                                Quiccz
                                wrote on last edited by
                                #14

                                @Pl45m4 If I don't use repaint(), the display effect of case 1 will become like video 2. However, the logs indicate that the paintEvent of the picture has already finished, so why isn't it immediately displayed?

                                1 Reply Last reply
                                0
                                • Q Quiccz has marked this topic as solved on
                                • Q Offline
                                  Q Offline
                                  Quiccz
                                  wrote on last edited by
                                  #15

                                  I found my program bug. so close it

                                  1 Reply Last reply
                                  0
                                  • S Offline
                                    S Offline
                                    SimonSchroeder
                                    wrote on last edited by
                                    #16

                                    There is no reason to call show() or hide() on your pictures. Just show and hide the parent widgets.

                                    Here is my try to explain why with the order show() -> showAll() the pictures can appear one after the other. You are correct that the basic understanding of signals and slots is that events are queued inside the event loop. However, the default connection is an AutoConnection. If both sender and receiver are inside the same thread this defaults to a DirectConnection. This means that the event loop is skipped. This is especially true for repaint() which will immediately draw the widget. Because you are doing this in a loop (and PicWidget::paintEvent() has a delay) one picture must appear after the other. The general advice is to never use repaint(), but use update() instead. This can significantly increase performance. update() will gather several calls first if they appear quickly after another and only then call repaint(). I am not entirely sure about the underlying mechanism of update() or if the event loop is involved. show() itself will call update() (or something similar) internally. This means that several calls to show() also are first gathered.

                                    With the order showAll() -> show() nothing will happen when calling show() for each picture because their parent widget is not visible. They are basically marked as visible and that's it. I don't think repaint() will do anything here as well. Only when show() is called on the parent will all the pictures be drawn. As this is a single paintEvent on the parent widget it will not be interrupted (drawing all of its children) before it can be shown on the screen (Qt does not paint on the screen directly, but uses double buffering, so that only after all draw commands of a single update() call are finished will they show on the screen). Just as I said in the beginning: Don't ever call show/hide on your PicWidgets. Just call it on the parent which will manage all the rest.

                                    @Quiccz said in Question about show() hide():

                                    I found my program bug. so close it

                                    This is up to you. If you found a particular answer useful, click the three dots of that answer and mark the post as solved. Otherwise post your solution for others to find and select that one as the correct answer. (Somewhere there is also an option to mark it as solved without selecting an answer.)

                                    Q 1 Reply Last reply
                                    3
                                    • S SimonSchroeder

                                      There is no reason to call show() or hide() on your pictures. Just show and hide the parent widgets.

                                      Here is my try to explain why with the order show() -> showAll() the pictures can appear one after the other. You are correct that the basic understanding of signals and slots is that events are queued inside the event loop. However, the default connection is an AutoConnection. If both sender and receiver are inside the same thread this defaults to a DirectConnection. This means that the event loop is skipped. This is especially true for repaint() which will immediately draw the widget. Because you are doing this in a loop (and PicWidget::paintEvent() has a delay) one picture must appear after the other. The general advice is to never use repaint(), but use update() instead. This can significantly increase performance. update() will gather several calls first if they appear quickly after another and only then call repaint(). I am not entirely sure about the underlying mechanism of update() or if the event loop is involved. show() itself will call update() (or something similar) internally. This means that several calls to show() also are first gathered.

                                      With the order showAll() -> show() nothing will happen when calling show() for each picture because their parent widget is not visible. They are basically marked as visible and that's it. I don't think repaint() will do anything here as well. Only when show() is called on the parent will all the pictures be drawn. As this is a single paintEvent on the parent widget it will not be interrupted (drawing all of its children) before it can be shown on the screen (Qt does not paint on the screen directly, but uses double buffering, so that only after all draw commands of a single update() call are finished will they show on the screen). Just as I said in the beginning: Don't ever call show/hide on your PicWidgets. Just call it on the parent which will manage all the rest.

                                      @Quiccz said in Question about show() hide():

                                      I found my program bug. so close it

                                      This is up to you. If you found a particular answer useful, click the three dots of that answer and mark the post as solved. Otherwise post your solution for others to find and select that one as the correct answer. (Somewhere there is also an option to mark it as solved without selecting an answer.)

                                      Q Offline
                                      Q Offline
                                      Quiccz
                                      wrote on last edited by
                                      #17

                                      @SimonSchroeder The reason I use show ()/hide() for pics is that in my actual project, each picture has a different display duration. For example, if there are three pictures in total, initially they are all displayed. After 1 second, the first picture is hidden. After 2 seconds, the second picture is hidden. After 3 seconds, the third picture is hidden, and then it switches to the next set of pictures.

                                      1 Reply Last reply
                                      0
                                      • Q Quiccz has marked this topic as unsolved on
                                      • Q Quiccz has marked this topic as solved on

                                      • Login

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