Hide and show UI's
-
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.
-
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();
}@
-
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 -
got the answer from below link:
I should write below line in main function.
app.setQuitOnLastWindowClosed(false);
-
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_OBJECTpublic:
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_OBJECTpublic:
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_OBJECTpublic:
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_OBJECTpublic:
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();
}@
-
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();
}@
-
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(); -
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();