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. QStackedWidget::setCurrentWidget has no effect
QtWS25 Last Chance

QStackedWidget::setCurrentWidget has no effect

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 2.5k 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.
  • A Offline
    A Offline
    ajaxcrypto
    wrote on 12 Sept 2017, 19:37 last edited by
    #1

    I have a navigation setup inside the application using QStackedWidget. I am using Qt 5.9.0 with MSVC 2015. On clicking a button, the slot calls QStackedWidget::setCurrentIndex , which sets the current widget to index-th widget. The widget itself has a nested QStackedWidget and thus it further calls setCurrentWidget to set the current nested widget. However, none of setCurrentIndex and setCurrentWidget works. Also, in the slot emits a signal, whose handler does a similar change, which happens fine.

    QObject::connect(button, &QPushButton::clicked, [this](bool toggle){
        topStackedWidget->setCurrentIndex(some_index); //nothing happens
        childStackedWidget->setCurrentWidget(waiting_animation_widget); //nothing happens
        // ...some time taking operation...
        emit customSignal(); // The slot for this signal also calls setCurrentIndex/Widget  on topStackedWidget which works fine...
    

    Nothing happens here implies that the widget in view does not change, it remains the same.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 12 Sept 2017, 20:25 last edited by
      #2

      Hi,

      The important line is: // ...some time taking operation.... You are likely blocking the event loop thus your stacks don't have the possibility to update before you emit customSignal.

      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
      0
      • A Offline
        A Offline
        ajaxcrypto
        wrote on 12 Sept 2017, 20:36 last edited by
        #3

        What should then be the approach? Delegate the operation to a separate thread? i.e. spawn a QThread, let it finish, wait for the thread finished signal and continue ? Also, note that the operation can throw exceptions which I need to display in the GUI.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 12 Sept 2017, 20:39 last edited by
          #4

          Yes, you should encapsulate that work properly using e.g. the worker object approach.

          For the GUI update in case of an error, design your worker object or QThread based object so that it emit a signals to signal an error and also an accessor function to retrieve the information you want to show.

          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
          0
          • A Offline
            A Offline
            ajaxcrypto
            wrote on 12 Sept 2017, 21:34 last edited by
            #5

            I created a worker object based on this:

            class Worker : public QObject {
                Q_OBJECT;
            public:
                void operate() {
                    bool ret;
                    try { ret = expensive_op(); } catch (...) { emit error(code); ret = false; }
                    emit done(ret);
                }
            
            signals:
                void done(bool);
                void error(int);
            
            };
            

            In my GUI class, I have a QThread instance. So, in the slot where I need to do the operation, the code is as follows:

            void myslot() {
                // ... code updating the stacked widget...
                auto worker = new Worker;
                worker->moveToThread(m_thread);
                // ... code for handling the signals error and done
                m_thread.start();
                worker->operate();
            }
            

            However, the result is identical, the QStackedWidget is not updated. I think I must be doing something wrong/not understanding the worker/QThread model. What is the correct approach ?

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 12 Sept 2017, 21:44 last edited by SGaist
              #6

              The error is the way you call operate. Moving your object in another thread won't help if you still call the expensive operation yourself from the main thread. You should connect the QThread::started signal to your Worker operate method which you should make a slot.

              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
              2
              • A Offline
                A Offline
                ajaxcrypto
                wrote on 13 Sept 2017, 05:11 last edited by
                #7

                Thank you for the guidance! I got it working.

                1 Reply Last reply
                0

                6/7

                12 Sept 2017, 21:44

                • Login

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