PDA

View Full Version : Qt Creator - Main widow and second window



Kuushie118
28th December 2018, 04:18
how do you hide the main Window after opening the second Window?Also, when the second Window is closed by the user, how can the main window reappear?

these are the codes I have so far.
I have an error that says ERROR:no matching constructor for initialization 'Dialog'...it's at the mainwindow.cpp ...this is the only error I have. Please help me fix it.

.H FILES

mainwidow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();

public:
void show();



private slots:
void on_pushButton_clicked();

private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H



secwindow.h


#ifndef SECWINDOW_H
#define SECWINDOW_H

#include <QDialog>

namespace Ui {
class SecWindow;
}

class SecWindow : public QDialog
{
Q_OBJECT

public:
explicit SecWindow(QWidget *parent = nullptr);
~SecWindow();


private:
Ui::SecWindow *ui;
};

class Dialog : public QDialog
{
public:
Dialog();

private:
Dialog *dialog;

};


#endif // SECWINDOW_H


SOURCE CODE

main.cpp


#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setQuitOnLastWindowClosed(false);
MainWindow w;
w.show();

return a.exec();
}


mainwindow.cpp


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPixmap>
#include "secwindow.h"
#include <QDialog>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPixmap pix("C:/Users/Charlene/Downloads/Charlene Back-up/MAPUA/2nd Term/Object Oriented Programming/GOW-Gui/GOW-GUI/intro pic/intro.png");
ui->label->setPixmap(pix.scaled(230,250,Qt::KeepAspectRatio)) ;

// QWidget *wdg = new QWidget;
//wdg->show();
//hide();
}

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

void MainWindow::on_pushButton_clicked() // Modal approach..mainwindow cannot be moved when secwindow is displayed.
{
SecWindow secwindow;
secwindow.setModal(true); //it'll set the secwindow
secwindow.exec(); //shows secwindow when button is pressed
}

void MainWindow::show()
{
Dialog *dialog = new Dialog(this); //ERROR: no matching constructor for initialization of 'Dialog'
connect(dialog, SIGNAL(accepted()), this, SLOT(show()));
connect(dialog, SIGNAL(rejected()), this, SLOT(show()));
dialog->show();
hide();
};



secwindow.cpp


#include "secwindow.h"
#include "ui_secwindow.h"
#include <QPixmap>

SecWindow::SecWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::SecWindow)
{
ui->setupUi(this);
QPixmap pix("C:/Users/Charlene/Downloads/Charlene Back-up/MAPUA/2nd Term/Object Oriented Programming/GOW-Gui/GOW-GUI/images/102.gif");
ui->label_2 ->setPixmap(pix.scaled(100,95, Qt::KeepAspectRatio));
}

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

ChrisW67
28th December 2018, 05:48
how do you hide the main Window after opening the second Window?Also, when the second Window is closed by the user, how can the main window reappear?

these are the codes I have so far.
I have an error that says ERROR:no matching constructor for initialization 'Dialog'...it's at the mainwindow.cpp ...this is the only error I have. Please help me fix it.

The error message is because there is no class named "Dialog". Did you perhaps mean QDialog?

Without a modal window (i.e. no call to exec()) this is one way to go about it:


#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
#include <QCloseEvent>

class SecondWindow: public QWidget {
Q_OBJECT
public:
explicit SecondWindow(QWidget *parent = nullptr);
~SecondWindow();
protected:
void closeEvent(QCloseEvent *event);
signals:
void closing();
};

SecondWindow::SecondWindow(QWidget *parent):
QWidget(parent)
{
// Dummy UI
QVBoxLayout *layout = new QVBoxLayout(this);
QLabel *l = new QLabel("The Second Widget", this);
layout->addWidget(l);
}

SecondWindow::~SecondWindow() { }

void SecondWindow::closeEvent(QCloseEvent *event)
{
emit closing();
event->accept();
}


class MainWindow: public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();

private slots:
void on_pushButton_clicked();
private:
SecondWindow *m_secondWindow;
};

MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent)
{
// Simple UI
QPushButton *pb = new QPushButton("Push Me", this);
connect(pb, SIGNAL(clicked()), this, SLOT(on_pushButton_clicked()));
setCentralWidget(pb);

// Second window ready to go
m_secondWindow = new SecondWindow();
connect(m_secondWindow, SIGNAL(closing()), this, SLOT(show()));
}

MainWindow::~MainWindow()
{
delete m_secondWindow;
}

void MainWindow::on_pushButton_clicked() {
hide();
m_secondWindow->show();
}

int main(int argc, char **argv) {
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
}

#include "main.moc"


Essentially you make the second window emit a signal as it closes and use that to unhide the main window.

Kuushie118
28th December 2018, 07:49
but sir, is there a way to fix my error?
My professor wants me to do it that way:(:(

you say that my error is that I don't have a class dialog.
but don't I have one at secwindow.h line 23??

Added after 59 minutes:

I edited the void MainWindow::show();



void MainWindow::show()
{
QDialog *dialog = new QDialog(this);
connect(dialog, SIGNAL(accepted()), this, SLOT(show()));
connect(dialog, SIGNAL(rejected()), this, SLOT(show()));
dialog->show();
hide();
};



there's no error anymore but it just doesn't show my main window.

it says that:
QObject::connect: (sender name: 'MainWindow')
QObject::connect: (receiver name: 'MainWindow')


It just shows like a blank window first, then when I close that blank window...my main window will appear(in this part, the modal approach still works)
how can I fix this please?

d_stranz
28th December 2018, 17:03
void MainWindow::show()
{
Dialog *dialog = new Dialog(this); //ERROR: no matching constructor for initialization of 'Dialog'
connect(dialog, SIGNAL(accepted()), this, SLOT(show()));
connect(dialog, SIGNAL(rejected()), this, SLOT(show()));
dialog->show();
hide();
};

As ChrisW67 said, your error is because you don't have any class named "Dialog". If you change Dialog to QDialog, then this code will compile, but it will create a completely empty, blank dialog (since a QDialog instance has no content, it's just an empty widget with a frame).

What you probably mean to do in this code is to create an instance of your "SecWindow" class and show that.

But there is a bigger problem here - you have chosen to name this method "show()", which overrides the QMainWindow::show() slot. So you are basically causing this method to execute itself over and over again. Here's what is probably actually happening in your code:

1 - You (or the Qt framework) call QMainWindow::show().
2 - Because you have overridden this method by implementing MainWindow::show(), your method gets called instead.
3 - Your method creates a QDialog and connects its signals to this MainWindow::show() method.
4 - The dialog then opens and the MainWindow is hidden.
5 - When you close the dialog, it executes the MainWindow::show() method again (because of the connection to the dialog's signals)
6 - This creates a -new- QDialog (different from the first one), and you go back to Step 3 of this list.

Each time you go through this loop, your code creates a new QDialog. Even though you close it by clicking OK or Cancel, it doesn't actually go away, it just becomes a ghost with a "dangling pointer". It isn't deleted, it just stays there invisible. The next time show() executes, it creates -another- QDialog instance, different from the first one, and it also ends up as an invisible ghost. And on and on.

(If you have not defined MainWindow::show() as a slot this might not happen, because the connect() statement only allows connection to slots if you use the version of connect() with the SIGNAL() and SLOT() macros. This could explain why Qt complains about your connect() calls. And if the connect() is failing, then closing the dialog won't make the MainWindow reappear).

The solution involves two fixes:

1 - Rename your MainWindow::show() to something else that isn't the name of a QMainWindow or other base class method, like showDialog() maybe. Then your connections to QMainWindow::show() will work correctly and Qt won't complain.
2 - Make your dialog a member variable of the MainWindow class and rewrite showDialog() so it simply uses the same SecWindow instance over and over:



// MainWindow.h:

class MainWindow : public QMainWindow
{
Q_OBJECT;

MainWindow( QWidget * parent );

// ...

private slots:
void showDialog();

private:
SecWindow * secWindow = nullptr;
};

// Mainindow.cpp

MainWindow::MainWindow( QWidget * parent ) : QMainWindow( parent )
{
secWindow = new SecWindow( this );
connect( secWindow, &SecWindow::accepted, this, &QMainWindow::show ); // connect to the real show() slot
connect( secWindow, &SecWindow::rejected, this, &QMainWindow::show );

// ...
}

void MainWindow::showDialog()
{
secWindow->show(); // Reuses the member instance of SecWindow
hide();
}

ChrisW67
28th December 2018, 22:11
but sir, is there a way to fix my error?
My professor wants me to do it that way:(:(

you say that my error is that I don't have a class dialog.
but don't I have one at secwindow.h line 23??


Actually, yes you do have a declaration of Dialog at that location. I misread the error message. While you do have a Dialog class, you do not have a Dialog class constructor that accepts an argument. Your code:


Dialog *dialog = new Dialog(this); //ERROR: no matching constructor for initialization of 'Dialog'

is passing an argument and this does not match any constructor you have declared:


class Dialog : public QDialog
{
public:
Dialog(); // <<<< no arguments accepted
...

Your Dialog constructor should have a similar declaration and implementation to the one you have for SecWindow.

d_stranz
29th December 2018, 16:15
Actually, yes you do have a declaration of Dialog at that location. I misread the error message.

And I didn't scroll the code window far enough. That definition of a Dialog class looks like a failed / confused attempt to get something working. A class that contains a pointer to an instance of itself as a member variable?

Kuushie118
30th December 2018, 04:29
Thanks for all the help guys, it finally worked ;);)