PDA

View Full Version : How to open another form in Qt4?



sapslaj
2nd September 2011, 01:04
Hello there! I am new to the forum, so just bear with me...

I am trying to open another form by clicking a button on the first form. I tried...


form1 w;
w.show();


And it shows form2 then immediately closes form2.



form1 w;
w->show();


Gives compiler error: "form1.cpp:84: error: base operand of '->' has non-pointer type 'form2'"



static Form2 *form2 = new Form2(this);
form2->show();
form2->activateWindow();
form2->raise();


gives compiler error: "form1.h:21: error: ISO C++ forbids declaration of 'Form2' with no type."
and error: "C:\Users\sapslaj\Desktop\chat-build-desktop\..\chat\mainlogin.h:21: error: expected ';' before '*' token"

I have tried everything I know possible, and I cannot get it to stay open. Any help?

wysota
2nd September 2011, 01:27
http://www.qtcentre.org/faq.php?faq=qt_general_category#faq_qt_designer_2f orms

sapslaj
2nd September 2011, 01:50
Its not QDialog derived. So still compiler errors.

Added after 5 minutes:

Here is the whole code.. Unmodified in any way.


#include "mainlogin.h"
#include "ui_mainlogin.h"
#include <QFile>
#include <QMessageBox>
#include "mainwin.h"
#include "ui_mainwin.h"
#include <QCloseEvent>
#include <QTextStream>


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

mainlogin::~mainlogin()
{
// do nothing
}

void mainlogin::on_bLogin_clicked()
{
mainlogin::login();
}

void mainlogin::login()
{
QFile loginsFile("/logins.txt");
/*
if(loginsFile.size() == 0 || loginsFile.exists() == false)
{
QMessageBox error;
error.setText("There are no logins stored. Please reinstall the program.");
error.exec();
return;
}*/
QTextStream loginsStream(&loginsFile);

QString enteredUsername = ui->leUsername->text();
QString enteredPassword = ui->lePassword->text();

QString loadedLogins = loginsStream.readAll();

int usernameCorrect = 0;

QString filedUsername = loadedLogins.section("|", 1, 1);
QString filedPassword = loadedLogins.section("|", 2, 2);

// for debug puposes only, until i can figure out whats causing all of the crap with the login.
filedUsername = "sapslaj";
filedPassword = "gamilo90";

//printf("enteredUsername: %s\nenteredPassword: %s\nloadedLogins: %s\nfiledUsername: %s\nfiledPassword: %s", enteredUsername.toStdString(), enteredPassword.toStdString(), loadedLogins.toStdString(), filedUsername.toStdString(), filedPassword.toStdString());

/*QMessageBox debug;
debug.setText(enteredUsername);
debug.exec();
debug.setText(enteredPassword);
debug.exec();
debug.setText(loadedLogins);
debug.exec();
debug.setText(filedUsername);
debug.exec();
debug.setText(filedPassword);
debug.exec();*/



if(enteredUsername != filedUsername)
{
QMessageBox error;
error.setText("Username not found!");
error.exec();
usernameCorrect = 0;
}

else
{
if(enteredPassword == filedPassword)
{
mainwin form(this);
form.exec();



//form2->show();
//form2->activateWindow();
//form2->raise();


//mainlogin::close();
}

else
{
QMessageBox error;
error.setText("Login Failed");
error.exec();
}
}
}

wysota
2nd September 2011, 02:28
Read the link again. There is no assumption about any dialog there.

ChrisW67
2nd September 2011, 03:36
I am trying to open another form by clicking a button on the first form. I tried...


form1 w;
w.show();

And it shows form2 then immediately closes form2.

What is the lifetime of the stack-allocated w object in C++? This is basic C++, not a Qt question.
Given that w.show() is non-blocking, why do you think the window might go away?





form1 w;
w->show();


Gives compiler error: "form1.cpp:84: error: base operand of '->' has non-pointer type 'form2'"

What do you think the error message is telling you? This is basic C++, not a Qt question. You might find some clues in your next snippet.





static Form2 *form2 = new Form2(this);
form2->show();
form2->activateWindow();
form2->raise();


gives compiler error: "form1.h:21: error: ISO C++ forbids declaration of 'Form2' with no type."
and error: "C:\Users\sapslaj\Desktop\chat-build-desktop\..\chat\mainlogin.h:21: error: expected ';' before '*' token"

Where is the class Form2 declared? This is basic C++, not a Qt question.

You may have noticed a theme in my questions. You have all the elements of the Qt side of this problem here and in the FAQ page wysota gave you but your C++ knowledge is letting you down.

sapslaj
2nd September 2011, 18:59
Well I posted in the Newbie forum for a reason, then... I'm not an expert at C++ at all. Now I will post the whole project if you want me to, so someone can help me out... I'm a full n00b at Qt. If someone can come up with a solution, so I can learn.

Added after 24 minutes:


Assuming you have two form classes: Form1 and Form2 and that Form1 has a pushbutton "button" child and Form2 is derived from QDialog.

It is not derived from QDialog.

wysota
2nd September 2011, 23:12
Well I posted in the Newbie forum for a reason, then...
The Newbie forum is for newbies in Qt, not newbies in programming. If you have problems with C++, post in "General Programming".


It is not derived from QDialog.
Did you even try following the advice?

sapslaj
3rd September 2011, 02:00
I'm not a noob to programming, I'm a noob to Qt. I have followed the advice line for line. It works with QDialog. Not QWidget for whatever reason. I'm not stating this as a problem with Qt. In fact, I love working with Qt. Best thing that has ever happened to me. But I'm a total noob at it. And I have no idea what I am doing wrong. We are all human, and we make mistakes. Now if you see a problem, I wish for you to just speak out. Don't try to make me figure it out on my own. I will probably never come back to this forum ever again, because I have had no problems with Qt up until this point. Although I have a love for Qt, and would be more than happy to help anybody on here if they have problems, you apparently have very little care for my problem. So forget I ever asked. You people apparently refuse to help me solve the problem. Although I appreciate what little help you did give me... I give up, and moving to another forum.

ChrisW67
3rd September 2011, 04:31
You have the entire problem solution in this thread: what more do you expect? The problems you are having are not Qt problems, they are C++ programming problems. Looking back a post #5 (/threads/44334-How-to-open-another-form-in-Qt4?p=201956#post201956)....


Your first attempt fails because the object that creates and displays the widget goes out of scope.
Your second attempt fails because you try to treat an instance of an object as if it were a pointer to an object. These are not the same thing, and it would not matter if the object were not of Qt origin.
Your third attempt, which is almost exactly the solution in the FAQ you have been referred to, fails because you have tried to use a class that is not defined.

This forum operates on the basis that it is better to learn something than than simply copy and paste answers. So, here is a complete, didactic example:


#include <QtGui>

class SecondWidget: public QWidget {
Q_OBJECT
public:
SecondWidget(QWidget *p = 0): QWidget(p) {
setAttribute(Qt::WA_DeleteOnClose); // make sure memory is cleaned up
resize(320, 240);

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget( new QLabel("Label 1", this) );
layout->addWidget( new QLabel("Label 2", this) );
setLayout(layout);
}
};

class MainWindow: public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *p = 0): QMainWindow(p) {
QPushButton *pb = new QPushButton("Push me!", this);
connect(pb, SIGNAL(clicked()), SLOT(onClick()));
setCentralWidget(pb);
}
public slots:
void onClick() {
SecondWidget *a = new SecondWidget;
a->show();
}
private:
};

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

MainWindow m;
m.show();
return app.exec();
}
#include "main.moc"

Please try to learn from it. In particular, there is no reference to QDialog, the onClick() handler looks strikingly similar to your third attempt, the second widget opens on demand and stay open even if your close the first widget. I leave it as an exercise to limit the program to a single second widget.

sapslaj
3rd September 2011, 16:12
Your solution helped. I didn't exactly need direct code, I just needed a simple solution instead of someone asking me questions to figure this out. I taught myself C++ using absolutly no tutorials. I just examined other programs and figured out how they work. I couldn't find another program that had the solution I was trying to fix, but just that simple program that you posted is all I need. I can learn from that. Thanks.

wysota
3rd September 2011, 20:23
Your solution helped. I didn't exactly need direct code, I just needed a simple solution instead of someone asking me questions to figure this out. I taught myself C++ using absolutly no tutorials. I just examined other programs and figured out how they work. I couldn't find another program that had the solution I was trying to fix, but just that simple program that you posted is all I need. I can learn from that. Thanks.

Did you notice the code Chris gave you is identical to the one in the FAQ entry I posted?

ChrisW67
4th September 2011, 00:10
The example in the FAQ is subtly different although the intent is the same.

As written, the FAQ entry does require the second form to be a QDialog in order to function as expected. If you simply substitute a QWidget for QDialog in the FAQ example the widget is drawn as a child of the first form, not an independent window. This happens because the widget is parented. QDialog forces an independent window regardless of the dialog being parented. For example, with my code, line 7 commented and line 27 changed to:


static SecondWidget *a = new SecondWidget(this);

in line with the FAQ. This is the result after pushing the button (I enlarged the button to see more clearly):
6819
This is why I do not parent the widget when I create it. I assume this is what the OP was seeing (or not seeing) when trying the FAQ as-is.

wysota
4th September 2011, 15:16
I updated the FAQ entry a bit.