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. Hide and show UI's
Forum Updated to NodeBB v4.3 + New Features

Hide and show UI's

Scheduled Pinned Locked Moved General and Desktop
13 Posts 5 Posters 17.5k Views 1 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.
  • M Offline
    M Offline
    mrajanna
    wrote on last edited by
    #1

    Hello Folks,

    I have a question.

    I have 3 UI's. My requirement is any one UI should be visible at any point of time. I have push buttons on each UI's.

    My navigation between UI's are like below:

    Intially show first UI. On click of push button, first UI is hide and second UI is show --> This works
    On click of push button in second UI, second UI is hide and third UI is show --> This works
    On click of push button in third UI, third UI is hide and second UI is show and immediately entire application crashes with below warning.

    QDialog::exec: Recursive call detected

    FYI: In the second UI along with push button, I also have a list widget. For the first time when second UI was shown, list shall get populate with some data. During the navigation from third UI to second UI, I should be able to view the same hidden second UI.

    Please provide you help.

    Thanks
    Mohan

    1 Reply Last reply
    0
    • R Offline
      R Offline
      Rahul Das
      wrote on last edited by
      #2

      Take a look at [[doc:QStackedWidget]] . I hope, this will make your implementation a lot easier.


      Declaration of (Platform) independence.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mrajanna
        wrote on last edited by
        #3

        I don't want to implement similar to QTabWidget.

        My requirement would be like each UI should be shown as different independent windows.

        1 Reply Last reply
        0
        • R Offline
          R Offline
          Rahul Das
          wrote on last edited by
          #4

          First of all, [[doc:QStackedWidget]] is no way similar to tab widget (Atleast in appearance). Its a good idea, that you see the examples , to see what really a StackedWidget is,if you haven't gone through already.

          Now, any qwidget, you can "show":http://qt-project.org/doc/qt-4.8/qwidget.html#show or "hide":http://qt-project.org/doc/qt-4.8/qwidget.html#hide, if you want to do it separately.


          Declaration of (Platform) independence.

          1 Reply Last reply
          0
          • Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #5

            It sounds like you are showing dialogs by calling exec() on them. This eventually causes that you call exec inside exec inside exec...
            Instead try to create all three windows and show()/hide() them in the same event loop. Something similar to this:
            @#include <QApplication>
            #include <QPushButton>

            int main(int argc, char *argv[])
            {
            QApplication a(argc, argv);

            QPushButton pb1("Window 1");
            QPushButton pb2("Window 2");
            
            QObject::connect(&pb1, SIGNAL(clicked()), &pb1, SLOT(hide()));
            QObject::connect(&pb1, SIGNAL(clicked()), &pb2, SLOT(show()));
            
            QObject::connect(&pb2, SIGNAL(clicked()), &pb2, SLOT(hide()));
            QObject::connect(&pb2, SIGNAL(clicked()), &pb1, SLOT(show()));
            
            pb1.show();
            
            return a.exec(&#41;;
            

            }@

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mrajanna
              wrote on last edited by
              #6

              Hello Krzyszt,

              I tried your suggestion but din't work out.

              As I told I have 3 GUI's

              In first GUI window, on click of push button, progress bar pops up. Once progress bar completes with 100%, I shall hide first GUI window and then show second GUI.

              Second GUI window has a list widget(list items were captured during progress bar in first GUI window).
              On click of list item, I shall hide second GUI and then show third GUI.

              In third GUI when I click close button, I call close() to close third GUI and subsequently after this close operation I shall show second GUI. Unfortunately second GUI window pops and immediately entire application quits by showing "QDialog::exec: Recursive call detected"

              Thanks,
              Mohan

              1 Reply Last reply
              0
              • M Offline
                M Offline
                mrajanna
                wrote on last edited by
                #7

                got the answer from below link:

                I should write below line in main function.

                app.setQuitOnLastWindowClosed(false);

                http://stackoverflow.com/questions/5116459/problem-with-hidden-qmainwindow-application-crashes-after-qmessagebox-is-displa

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  Macro
                  wrote on last edited by
                  #8

                  Try this... Hope this Example will be useful for you...

                  FirstDialog.h
                  @#ifndef FIRSTDIALOG_H
                  #define FIRSTDIALOG_H

                  #include "qthideandshowdialog.h"

                  namespace Ui {
                  class FirstDialog;
                  }

                  class FirstDialog : public QtHideAndShowDialog
                  {
                  Q_OBJECT

                  public:
                  explicit FirstDialog(QWidget *parent = 0);
                  ~FirstDialog();

                  private slots:
                  void on_pushButton_clicked();

                  private:
                  Ui::FirstDialog *ui;
                  };

                  #endif // FIRSTDIALOG_H@

                  FirstDialog.cpp
                  @
                  #include "seconddialog.h"
                  #include "firstdialog.h"
                  #include "ui_firstdialog.h"

                  FirstDialog::FirstDialog(QWidget *parent) :
                  QtHideAndShowDialog(parent),
                  ui(new Ui::FirstDialog)
                  {
                  ui->setupUi(this);
                  }

                  FirstDialog::~FirstDialog()
                  {
                  delete ui;
                  }

                  void FirstDialog::on_pushButton_clicked()
                  {
                  SecondDialog d;
                  this->ShowChild(&d);
                  }@

                  SecondDialog.h

                  @#ifndef SECONDDIALOG_H
                  #define SECONDDIALOG_H

                  #include "qthideandshowdialog.h"

                  namespace Ui {
                  class SecondDialog;
                  }

                  class SecondDialog : public QtHideAndShowDialog
                  {
                  Q_OBJECT

                  public:
                  explicit SecondDialog(QWidget *parent = 0);
                  ~SecondDialog();

                  private slots:
                  void on_button_goto_third_clicked();

                  void on_button_back_to_first_clicked();

                  private:
                  Ui::SecondDialog *ui;
                  };

                  #endif // SECONDDIALOG_H@

                  SecondDialog.cpp

                  @#include <cassert>
                  #include "seconddialog.h"
                  #include "ui_seconddialog.h"
                  #include "thirddialog.h"

                  SecondDialog::SecondDialog(QWidget *parent) :
                  QtHideAndShowDialog(parent),
                  ui(new Ui::SecondDialog)
                  {
                  ui->setupUi(this);
                  }

                  SecondDialog::~SecondDialog()
                  {
                  delete ui;
                  }

                  void SecondDialog::on_button_back_to_first_clicked()
                  {
                  close();
                  }

                  void SecondDialog::on_button_goto_third_clicked()
                  {
                  ThirdDialog d;
                  this->ShowChild(&d);
                  if (d.m_back_to_which_dialog == 1)
                  {
                  this->close();
                  }
                  }@

                  ThirdDialog.h

                  @#ifndef THIRDDIALOG_H
                  #define THIRDDIALOG_H

                  #include "qthideandshowdialog.h"

                  namespace Ui {
                  class ThirdDialog;
                  }

                  class ThirdDialog : public QtHideAndShowDialog
                  {
                  Q_OBJECT

                  public:
                  explicit ThirdDialog(QWidget *parent = 0);
                  ~ThirdDialog();

                  int m_back_to_which_dialog;
                  

                  private slots:
                  void on_button_back_to_first_clicked();

                  void on_button_back_to_second_clicked();
                  

                  private:
                  Ui::ThirdDialog *ui;
                  };

                  #endif // THIRDDIALOG_H@

                  ThirdDialog.cpp

                  @#include "thirddialog.h"
                  #include "ui_thirddialog.h"

                  ThirdDialog::ThirdDialog(QWidget *parent) :
                  QtHideAndShowDialog(parent),
                  m_back_to_which_dialog(2), //When user closes the dialog, go back to the previous/second dialog
                  ui(new Ui::ThirdDialog)
                  {
                  ui->setupUi(this);
                  }

                  ThirdDialog::~ThirdDialog()
                  {
                  delete ui;
                  }

                  void ThirdDialog::on_button_back_to_first_clicked()
                  {
                  m_back_to_which_dialog = 1;
                  close();
                  }

                  void ThirdDialog::on_button_back_to_second_clicked()
                  {
                  m_back_to_which_dialog = 2;
                  close();
                  }@

                  QtHideandShowDialog.h

                  @#ifndef QTHIDEANDSHOWDIALOG_H
                  #define QTHIDEANDSHOWDIALOG_H

                  #include <QDialog>

                  class QtHideAndShowDialog : public QDialog
                  {
                  Q_OBJECT

                  public:
                  explicit QtHideAndShowDialog(QWidget *parent = 0);

                  ///Virtual destructor as this is a base class
                  virtual ~QtHideAndShowDialog() {}

                  ///Show a child
                  void ShowChild(QtHideAndShowDialog * const dialog);

                  protected:
                  ///Shows a child until it emits a close_me signal
                  bool m_show_child;

                  ///closeEvent that emits the close_me signal
                  void closeEvent(QCloseEvent *);

                  signals:
                  ///Emit the closeEvent of this dialog
                  void close_me();

                  protected slots:
                  ///Slot that needs to be called when a child signals close_me
                  void close_child();

                  };

                  #endif // QTHIDEANDSHOWDIALOG_H@

                  QtHideandShowDialog.cpp

                  @#include <cassert>
                  #include "qthideandshowdialog.h"

                  QtHideAndShowDialog::QtHideAndShowDialog(QWidget *parent)
                  : QDialog(parent),
                  m_show_child(false)
                  {

                  }

                  void QtHideAndShowDialog::close_child()
                  {
                  m_show_child = false;
                  }

                  void QtHideAndShowDialog::closeEvent(QCloseEvent *)
                  {
                  emit close_me();
                  }

                  void QtHideAndShowDialog::ShowChild(QtHideAndShowDialog * const dialog)
                  {
                  assert(dialog);
                  this->hide();
                  QObject::connect(dialog,SIGNAL(close_me()),this,SLOT(close_child()));
                  m_show_child = true;
                  while (m_show_child)
                  {
                  dialog->exec();
                  }
                  this->show();
                  }

                  @

                  1 Reply Last reply
                  0
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    I think you complicate things too much.
                    I used two widgets in my example to be brief, but the idea is the same.

                    You should be careful when using setQuitOnLastWindowClosed(false), because your app won't close now when you close the last window and will dangle in memory. To terminate you will have to call app.quit() or app.exit(code). You would have to call it in the close event of all the windows with some conditions.

                    This pattern doesn't have these drawbacks. When you press the "x" in any window the app will close properly:

                    @#include <QApplication>
                    #include <QPushButton>
                    #include <QListWidget>
                    #include <QStringList>

                    int main(int argc, char *argv[])
                    {
                    QApplication a(argc, argv);

                    QPushButton pb1("First window.\nI'll skip progress bar but you can do it the same way");
                    QListWidget lw2;
                    QPushButton pb3("Dialog with close button");
                    
                    lw2.addItems(QStringList() << "item1" << "item2" << "item3");
                    
                    QObject::connect(&pb1, SIGNAL(clicked()), &pb1, SLOT(hide()));
                    QObject::connect(&pb1, SIGNAL(clicked()), &lw2, SLOT(show()));
                    
                    QObject::connect(&lw2, SIGNAL(itemClicked(QListWidgetItem*)), &lw2, SLOT(hide()));
                    QObject::connect(&lw2, SIGNAL(itemClicked(QListWidgetItem*)), &pb3, SLOT(show()));
                    
                    QObject::connect(&pb3, SIGNAL(clicked()), &pb3, SLOT(hide()));
                    QObject::connect(&pb3, SIGNAL(clicked()), &lw2, SLOT(show()));
                    
                    pb1.show();
                    
                    return a.exec&#40;&#41;;
                    

                    }@

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      Macro
                      wrote on last edited by
                      #10

                      Cool....

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        mrajanna
                        wrote on last edited by
                        #11

                        Hello Krzyszt,
                        Yes you are right.
                        To close windows I am using qApp->closeallwindows()

                        1 Reply Last reply
                        0
                        • D Offline
                          D Offline
                          deesha
                          wrote on last edited by
                          #12

                          Hey i also have the same problem, and none of the sollutions above have worked for me so far i need to hide a form(form2) before i exec() a new dialog(form 3), and immediately after exec returns on close of that dialog(form 3), i call this->show on the form 2. But the form 2 never shows and i get the form 1 on closing form 3. i hv also noticed that replacing exec() calls to form 2 and 3 by show() and creating the child dialogs on the heap , does not hide form 1 and 2 respectively when form 2 n 3 shows , they stay visible though... Please please let me know if anybody knows what i am missing. below is a part of the code method 1 (this returns to form 1 on closing form 3 with close())

                          form3 f3;
                          this->hide();
                          f3.exec();
                          this->show();

                          method 2 (this never hides from 2 but returns to form 2 on closing form3 with close())

                          f3=new Menu(this);
                          this->hide();
                          f3->show();
                          this->show();

                          1 Reply Last reply
                          0
                          • D Offline
                            D Offline
                            deesha
                            wrote on last edited by
                            #13

                            Hey i also have the same problem, and none of the sollutions above have worked for me so far i need to hide a form(form2) before i exec() a new dialog(form 3), and immediately after exec returns on close of that dialog(form 3), i call this->show on the form 2. But the form 2 never shows and i get the form 1 on closing form 3. i hv also noticed that replacing exec() calls to form 2 and 3 by show() and creating the child dialogs on the heap , does not hide form 1 and 2 respectively when form 2 n 3 shows , they stay visible though... Please please let me know if anybody knows what i am missing. below is a part of the code method 1 (this returns to form 1 on closing form 3 with close())

                            form3 f3;
                            this->hide();
                            f3.exec();
                            this->show();

                            method 2 (this never hides from 2 but returns to form 2 on closing form3 with close())

                            f3=new Menu(this);
                            this->hide();
                            f3->show();
                            this->show();

                            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