PDA

View Full Version : QDialog and QMainWindow Data Transfer



Ahmad
5th May 2007, 01:30
Can anyone guide me,
i have created my MainWindow and in its constructor i call a Dialog window named LoginWindow which inherits QDialog, this Dialog is modal and made of two lineEdits and three Buttons my problem is that i want when user clicks the "validerButton", i can transfer the texts typed by the user in the LineEdits to my MainWindow from where i called this Dialog.


this is my MainWindow s constructor

MainWindow::MainWindow()
{
createActions();
createMenus();
createToolBars();
createStatusBar();

readSettings();

//this is where my problem starts
login = new Loginwindow(this);

login->show();
//i tried this but i get a segmentation error
connect (login->validerButton, SIGNAL(clicked()), this, SLOT(getNames()));
}

void MainWindow::getNames()
{
QString text;
text = login->getNumetudLineEdit();
}

i send u also my LoginWindow


Loginwindow::Loginwindow(QWidget * parent) : QDialog (parent)
{
//construction des labels et des lignes edit

NumetudLabel = new QLabel(tr("&Numero Etudiant:"));
NumetudLineEdit = new QLineEdit;
NumetudLabel->setBuddy(NumetudLineEdit);

CodesecretLabel = new QLabel(tr("&Code Secret:"));
CodesecretLineEdit = new QLineEdit;
CodesecretLabel->setBuddy(CodesecretLineEdit);

QPushButton * inscriptionButton;
QPushButton * inviteButton;
QPushButton * validerButton;

inscriptionButton = new QPushButton(tr("&S'inscrire"));
inscriptionButton->setDefault(true);
inviteButton = new QPushButton(tr("&Invité"));
validerButton = new QPushButton(tr("&Valider"));

//disposition des layouts
topLeftLayout = new QVBoxLayout;
topLeftLayout->addWidget(NumetudLabel);
topLeftLayout->addWidget(NumetudLineEdit);
topLeftLayout->addWidget(CodesecretLabel);
topLeftLayout->addWidget(CodesecretLineEdit);

rightLayout = new QVBoxLayout;
rightLayout->addWidget(validerButton);
rightLayout->addWidget(inscriptionButton);
rightLayout->addWidget(inviteButton);
rightLayout->addStretch();

//QVBoxLayout *leftLayout = new QVBoxLayout;
//leftLayout->addLayout(topLeftLayout);

mainLayout = new QHBoxLayout;
mainLayout->addLayout(topLeftLayout);
mainLayout->addLayout(rightLayout);
this->setLayout(mainLayout);

this->setWindowTitle(tr("Login"));
this->setModal(true);
this->setSizeGripEnabled(false);
//setFixedHeight(sizeHint().height());

//les signaux et slots
connect(validerButton, SIGNAL(clicked()), this, SLOT(Valider()));
}

Pls help me, it would be nice of u

wysota
5th May 2007, 08:40
But what is the problem? If you have a pointer to the dialog then just access appropriate members of the dialog (either directly if they are public or through some getter method you need to implement).

Teerayoot
5th May 2007, 12:07
//i tried this but i get a segmentation error connect (login->validerButton, SIGNAL(clicked()), this, SLOT(getNames()));

you have to connect signal before

login->show();

marcel
5th May 2007, 12:32
//i tried this but i get a segmentation error connect (login->validerButton, SIGNAL(clicked()), this, SLOT(getNames()));

you have to connect signal before

login->show();

Why is that? Signals can be connected and disconnected dynamically - therefore it shouldn't matter where/when you connect a signal.

Regards

Teerayoot
5th May 2007, 13:01
ohh,i never know before.
i alway connect signal after object create.
Thank you.

jpn
5th May 2007, 13:01
Sounds like either login or validerButton is an uninitialized pointer.

marcel
5th May 2007, 13:10
Sounds like either login or validerButton is an uninitialized pointer.

No, they're OK both ( look at the code in the first post ).
I am more concerned with the fact that some of the widgets in the loginwindow do not have parents, and that the dialog is modal.

Too laisy now to make my own example and test it ( it's saturday http://www.qtcentre.org/forum/images/icons/icon6.png)

regards

Ahmad
5th May 2007, 14:21
TNX EVERYONE FOR UR REPLIES
but i still have problems, the problem is the same, i dont want to get the text that the user types directly when he clicks validerButton, it would have been easy, but i want to pass by a a validation methode, i should test if this is the text that i want... and if it is ok i should pass that text to my MainWindow, otherwise i should always stay in my LoginWindow which is a Modal Dialog, i send u an example of what i want with this... but as always i get a segmentation error
tnx for ur helps and suggestions,

lots of code parts are not concerned with this problem but i send u all of the code and the variable names are in french, so hope u dont get bored with them.. lol

marcel
5th May 2007, 14:38
Hey, I kind of found your error:

It was in the contstructor of your loginwindow, because you had:



QPushButton * inscriptionButton;
QPushButton * inviteButton;
QPushButton * validerButton;

inscriptionButton = new QPushButton(tr("&S'inscrire"), this);
inscriptionButton->setDefault(true);
//inscriptionButton->setEnabled(true); Pas besoin de le mettre, par defaut

//le & plac�devant annuler sert a creer un raccourci avec alt + a
inviteButton = new QPushButton(tr("&Invité"), this);

Look at the first three lines. You redeclared the push buttons here. They are also members. If you remove those three lines, it is OK.

Here's the main wnd constructor, which I used when testing.


MainWindow::MainWindow()
{
createActions();
createMenus();
createToolBars();
createStatusBar();

readSettings();

login = new Loginwindow(this);
login->show();
QString text;
QString text2;

connect( login->validerButton, SIGNAL( clicked() ), this, SLOT( getNames() ) );
}


Anyway, your solution is not so good.
Why don't you emit a signal for LoginWindow::Valider, which will be connected to the main window, in the slot getNames. When you press "validate" you don't know if the data is valid ( I assume that Valider() decides if the entered data is correct ), therefore Valider() should emit a signal to indicate the data is correct.

Regards

wysota
5th May 2007, 15:47
How about using a QValidator object to validate the input directly in the text field? You can then emit a signal from your validate() method and connect it to a button that accepts the dialog (like "Ok", "Login" or whatever you have there) to automatically enable/disable the button to make sure the user can't leave the dialog without entering proper data. Also remember to reimplement the close event to prevent the user from closing the window without entering proper data (unless you want him to be able to cancel the dialog).

chikkireddi
5th May 2007, 18:19
1) In Loginwindow::Valider() emit the signal with an argument QVariant, in your case CodesecretLineEdit.text() becomes QVariant


Loginwindow::Valider()
{
emit validerButtonClicked(CodesecretLineEdit.text());
}

2) Listen to the above signal validerButtonClicked in MainWindow class


MainWindow::MainWindow()
{
connect (login, SIGNAL(validerButtonClicked(const QVariant &)), this, SLOT(ValiderAction(QVariant &)));
}


MainWindow::ValiderAction(QVariant value)
{
// now data has come to your mainwindow
// do whatever u want.
}

Thanks
c v rao.

Ahmad
6th May 2007, 00:56
Tnx everyone,
i find the solution for my problem, in fact the post by Teerayoot was not bad, i putted everytime my signal connection in mainWindow after the login-> exec() function and that was the problem, once i putted just after the creation of login and before its execution, it worked , woow i m happy :D

marcel
6th May 2007, 07:02
i find the solution for my problem, in fact the post by Teerayoot was not bad, i putted everytime my signal connection in mainWindow after the login-> exec() function and that was the problem, once i putted just after the creation of login and before its execution, it worked , woow i m happy :D


I do not agree with this.

As jpn said in a previous post, you got a segfault because of an invalid pointer. But this pointer was not invalid because you didn't initialized it, but because you had the same variable declared as member and as local, in the constructor of the login window. This caused the local var to be initialiased, the member remaining invalid.

This can be seen very well in the code you posted.

So, you either modified this too ( once you did this, you could have moved the connect anywhere - given that the objects were created - it still would have worked ), or you have completely rewritten parts of your code.

But by simply moving the connect to another line you will never make it work.

Regards