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

How to handle a change of the current widget in QStackedWidget?



  • I found the following signal: void QStackedWidget::currentChanged(int index).
    But I don’t understand how it works or how I use it. Index holds the index of the new current widget. What it means? What am I supposed to give this signal?

    What I want is QStackedWidget, which contains 3 widgets. These 3 widgets are just initialized and added using the function:

    // Example: 
    QWidget *widget1 = new QWidget(parent);
    parent->insertWidget(0, widget1);
    // It’s the same for every widget. 
    

    I don’t want to draw a widget unless it is current. So I need to handle a event changing the current widget to render the widget contents using my function, which will create the layout and elements.
    If current widget is changed, I want to destroy the last one and render a new one.



  • call setCurrentIndex(int index) to display the one you want to. I do not think you want to destroy any. Otherwise, QStackedWidget is not needed.



  • @mingvv
    I have done it before so that the widgets are not created initially until the first time the user visits the page. But as @JoeCFD says, if you then wish to destroy the widget page when the user visits a different page, rather than keeping it around for re-use, then there is not much point using a QStackedWidget at all.



  • @JonB said in How to handle a change of the current widget in QStackedWidget?:

    @mingvv
    I have done it before so that the widgets are not created initially until the first time the user visits the page.

    How you did it?

    @JonB said in How to handle a change of the current widget in QStackedWidget?:

    @mingvv
    But as @JoeCFD says, if you then wish to destroy the widget page when the user visits a different page, rather than keeping it around for re-use, then there is not much point using a QStackedWidget at all.

    Can you offer another type of widget as a replacement?
    I don’t want to create a new window and delete the old one. Actually, I came from WPF, there are pages for it. So I can switch pages in one window. As I understood QStackedWidget is analogous to pages and I decided that I would be comfortable to pass from WPF using it.
    In principle, I don’t need to save the information when I go back (1<-2, 2<-3 etc.), but I need to pass it forward (0->1, 1->2, 2->3 etc.) through the pages.



  • @mingvv said in How to handle a change of the current widget in QStackedWidget?:

    How you did it?

    Looking at the code I didn't actually use QStackedWidget::currentChanged(), though I probably could have done. I had 14 pages in the app, and did not want the slowed start-up time to create them all initially. I have a menu of buttons for visiting the pages. These are QActions, which has triggerred signal, which is the equivalent of QStackedWidget::currentChanged.

    The QStackedWidget is initially populated with "placeholder" (empty) widgets:

    for pageName in self.PageNames:
        page = JPlaceHolder()
        page.setObjectName(str(pageName))
        self.pageStack.addWidget(page)
    

    Connect the QActions:

    for action in self.actions:
            action.setCheckable(True)
            self.addAction(action)
            action.triggered.connect(self.pageChange)
    

    And in the pageChange slot:

    def pageChange(self):
        action = self.sender()
        # find the index in self.actions of the action
        index = self.actions.index(action)
    
        widget = self.pageStack.widget(index)
        # if the widget is still a placeholder it has not been created yet
        if isinstance(widget, JPlaceHolder):
            name = self.PageNames(index)
            with ShowWaitCursor():
                self.createPage(name)
    

    Finally the createPage():

    def createPage(self, name):
        if name == self.PageNames.SearchPage:
            try:
                return self.searchPage
            except AttributeError:
                pass
            self.searchPage = page = SearchPage(self)
    
        elif name == self.PageNames....:
            ...
    
        # Now replace the placeholder widget in the page stack with the actual page created
        # The value of the self.PageNames enumeration gives the position of the page in the page stack
        index = int(name.value)
        widget = self.pageStack.widget(index)
        if isinstance(widget, JPlaceHolder):
            # if the widget in the page stack is a "placeholder"
            # we create the actual page now and replace the placeholder with the page
            self.pageStack.removeWidget(widget)
            widget.deleteLater()
            self.pageStack.insertWidget(index, page)
              
            return page                
    

    Whether it needs to be as much as this I don't recall. Perhaps you can just fill your QStackedWidget with nullptrs and create the pages in QStackedWidget::currentChanged(int index) when called, or maybe I found this didn't work if the page was nullptr....

    I don’t need to save the information when I go back (1<-2, 2<-3 etc.), but I need to pass it forward (0->1, 1->2, 2->3 etc.) through the pages.

    Have you looked at QWizard? That allows forward navigation through pages. You get backward navigation for free too, though if you don't want that you don't have to implement it/can forbid it. It's just a different kind of multi-page from QStackedWidget.


Log in to reply