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

problems with stacked widgets



  • Hi,

    I have some problems with stacked widgets.
    I tried QStackedLayout and selfwritten widget with QGridLayout.
    No matter what I do, the visual "defect" is always the same:

    Stacked007.png

    First time I switch through the pages, everything looks fine. But second time I select a page, only some child-widgets repaint itself.
    QTreeView and QTableView don't repaint itself.
    I tried to add widget->update and widget->repaint - it makes no difference. QTreeView and QTableView don't respond to mouseclicks / focus change.
    QPlainTextEdit, QLineEdit, QSplitter and QPushbutton always repaint itself.
    I tried to change size of mainwindow, but that does not change anything either.

    From java I know invalidate() for this sitation. Does Qt have something similar?



  • @django-Reinhard

    Do you have a QStackedWidget or a QStackedLayout ? (or both?!)

    Show what you did, so we can understand better.



  • Hi,

    as written - I tried QStackedLayout and own widget subclass with QGridLayout.
    Both showed the same behaviour.
    But I can only show the latter:

    MainView::MainView(QWidget* parent)
     : QWidget(parent) {
      setLayout(new QGridLayout);
      }
    
    
    void MainView::activatePage(const QString& name) {
      if (pages.contains(name)) {
         QWidget*     w  = pages[name];
         QGridLayout* gl = static_cast<QGridLayout*>(layout());
    
         if (gl) {
            w->setVisible(true);
            for (auto k = pages.keyBegin(); k != pages.keyEnd(); ++k) {
                if (!k->compare(name)) continue;
                pages[*k]->setVisible(false);
                }
            w->repaint();
            }
         }
      }
    
    
    void MainView::addPage(const QString& name, QWidget *page) {
      pages.insert(name, page);
      QGridLayout* gl = static_cast<QGridLayout*>(layout());
    
      if (gl) gl->addWidget(page, 0, 0);
      activatePage(name);
      }
    

    and this class was used like this:

    void MainWindow::createMainWidgets() {
      mainView = new MainView(this);
      view3D = new View(doc3D->getContext(), this);
      doc3D->setView(view3D);
      mainView->addPage("FileManager", new FileManager(QDir(QDir::homePath() + "/linuxcnc"), mainView));
      mainView->addPage("ToolManager", new ToolManager(mainView));
      mainView->addPage("Settings", new SettingsEditor("../QtUi/src/UI/Settings.ui", mainView));
      mainView->addPage("Preview", new PreViewEditor("../QtUi/src/UI/GCodeEditor.ui", view3D, mainView));
      this->setCentralWidget(mainView);
      }
    
    
    void MainWindow::selectPage(const QString& name) {
      qDebug() << "page to select: " << name;
      mainView->activatePage(name);
      }
    

    selectPage() is a public slot connected to different menue actions.

    Some additional tests showed, that the problems may be caused by View-class, which is borrowed from opencascade Qt-Samples and is an opengl window.



  • @django-Reinhard said in problems with stacked widgets:

    if (!k->compare(name)) continue

    try this out:
    if ( 0 != k->compare(name)) continue;

    k->compare(name) does not return true or false;
    when two strings are same, it returns 0;
    https://doc.qt.io/qt-5/qstring.html#compare



  • @JoeCFD said in problems with stacked widgets:

    k->compare(name) does not return true or false;
    when two strings are same, it returns 0;

    True and false are considered as 0 and 1 when using them in if-clauses.

    e.g.:

    if(0) // forever false
    
    if(1) // forever true
    


  • @Pl45m4 The problem here is
    when two strings are same, compare returns 0 which is false( do you like it?); False means they are not same in common logic.
    I would prefer to use 0 in the code instead of true or false to make sure I know what I am doing.



  • @JoeCFD
    QString::compare() returns 0/negative/positive a la strcmp(). While I personally, like you, do not write !string.compare() others do use that idiom, and the OP's

    if (!k->compare(name)) continue;
    

    behaves exactly the same as your

    if ( 0 != k->compare(name)) continue;
    

    Whatever the OP's problem elsewhere, this code is correct.


  • Lifetime Qt Champion

    @django-Reinhard hi,

    Which version of Qt are you using ?
    On which OS ?
    Can you provide a minimal compilable example that shows this behaviour ?



  • @JonB I think his logic might be

    if ( 0 == k->compare(name)) { /* if the name is the same, show it */
        continue;
    }
    else { /* if the name is different, hide it  */
       pages[*k]->setVisible(false);
    }
    

    The coders can easily get confused with true and false here. I never use true and false for string compare().



  • @SGaist said in problems with stacked widgets:

    Which version of Qt are you using ?
    On which OS ?

    I was on the way to switch all my projects to Qt6.2 but on recompiling latest opencascade I had to realize, that occ is not ready for Qt6xx - so I turned everything back to Qt5.15

    My OS is still debian 11

    @SGaist said in problems with stacked widgets:

    Can you provide a minimal compilable example that shows this behaviour ?

    Sorry, guess I can't do that. Each page is a single prototype and on merging all prototypes into the final app this issue came up. Its my first project using Qt and the first using occ - so most of all, I'm stumbling around ...



  • Just to close this ...

    ... I got help from occ forum.
    ... adding

      setAttribute(Qt::WA_NativeWindow);
    

    to the View-Constructor changed behaviour of the View-class - which now works as expected :)


Log in to reply