0

I am trying to create a User Login Page following this link. This is my header file formlogin.h:

#ifndef FORMLOGIN_H
#define FORMLOGIN_H

#include <QDialog>
#include <QLabel>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QLineEdit>
#include <QComboBox>
#include <QGridLayout>
#include <QStringList>
#include <QDebug>

/*!
 * Makes class LoginDialog a child to its parent, QDialog
*/
class LoginDialog : public QDialog
{
/*!
 * Turns Login Dialog into a QObject
*/
 Q_OBJECT

private:
 /*!
 * A label for the username component.
 */
 QLabel* labelUsername;

/*!
 * A label for the password.
 */
 QLabel* labelPassword;

/*!
 * An editable combo box for allowing the user
 * to enter his username or select it from a list.
 */
 QComboBox* comboUsername;

/*!
 * A field to let the user enters his password.
 */
 QLineEdit* editPassword;

/*!
 * The standard dialog button box.
 */
 QDialogButtonBox* buttons;

/*!
 * A method to set up all dialog components and
 * initialize them.
 */
 void setUpGUI();

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

 /*!
 * Sets the proposed username, that can come for instance
 * from a shared setting.
 * username the string that represents the current username
* to display
 */
 void setUsername( QString& username );

 /*!
 * Sets the current password to propose to the user for the login.
 * password the password to fill into the dialog form
 */
 void setPassword( QString& password );

 /*!
 * Sets a list of allowed usernames from which the user
 * can pick one if he does not want to directly edit it.
 * usernames a list of usernames
*/
 void setUsernamesList( const QStringList& usernames );

signals:

/*!
 * A signal emitted when the login is performed.
 * username the username entered in the dialog
 * password the password entered in the dialog
 * index the number of the username selected in the combobox
 */
 void acceptLogin( QString& username, QString& password, int& indexNumber );

public slots:
 /*!
 * A lot to adjust the emitting of the signal.
 */
 void slotAcceptLogin();

};

#endif // LOGINDIALOG_H

And this is my cpp file:

#include "formlogin.h"

LoginDialog::LoginDialog(QWidget *parent) :
 QDialog(parent)
{
 setUpGUI();
 setWindowTitle( tr("User Login") );
 setModal( true );
}

void LoginDialog::setUpGUI(){
 // set up the layout
 QGridLayout* formGridLayout = new QGridLayout( this );

// initialize the username combo box so that it is editable
 comboUsername = new QComboBox( this );
 comboUsername->setEditable( true );
 // initialize the password field so that it does not echo
 // characters
 editPassword = new QLineEdit( this );
 editPassword->setEchoMode( QLineEdit::Password );

// initialize the labels
 labelUsername = new QLabel( this );
 labelPassword = new QLabel( this );
 labelUsername->setText( tr( "Username" ) );
 labelUsername->setBuddy( comboUsername );
 labelPassword->setText( tr( "Password" ) );
 labelPassword->setBuddy( editPassword );

// initialize buttons
 buttons = new QDialogButtonBox( this );
 buttons->addButton( QDialogButtonBox::Ok );
 buttons->addButton( QDialogButtonBox::Cancel );
 buttons->button( QDialogButtonBox::Ok )->setText( tr("Login") );
 buttons->button( QDialogButtonBox::Cancel )->setText( tr("Abort") );

 // connects slots
 connect( buttons->button( QDialogButtonBox::Cancel ),
 SIGNAL (clicked()),
 this,
 SLOT (close())
 );

connect( buttons->button( QDialogButtonBox::Ok ),
 SIGNAL (clicked()),
 this,
 SLOT (slotAcceptLogin()) );

// place components into the dialog
 formGridLayout->addWidget( labelUsername, 0, 0 );
 formGridLayout->addWidget( comboUsername, 0, 1 );
 formGridLayout->addWidget( labelPassword, 1, 0 );
 formGridLayout->addWidget( editPassword, 1, 1 );
 formGridLayout->addWidget( buttons, 2, 0, 1, 2 );

setLayout( formGridLayout );

}

void LoginDialog::setUsername(QString &username){
 bool found = false;
 for( int i = 0; i < comboUsername->count() && ! found ; i++ )
 if( comboUsername->itemText( i ) == username ){
 comboUsername->setCurrentIndex( i );
 found = true;
 }

if( ! found ){
 int index = comboUsername->count();
 qDebug() << "Select username " << index;
 comboUsername->addItem( username );

comboUsername->setCurrentIndex( index );
 }

// place the focus on the password field
 editPassword->setFocus();
}

void LoginDialog::setPassword(QString &password){
 editPassword->setText( password );
}

void LoginDialog::slotAcceptLogin(){
 QString username = comboUsername->currentText();
 QString password = editPassword->text();
 int index = comboUsername->currentIndex();

emit acceptLogin( username, // current username
 password, // current password
 index // index in the username list
 );

// close this dialog
 close();
}

void LoginDialog::setUsernamesList(const QStringList &usernames){
 comboUsername->addItems( usernames );
}

And this is how I am trying to execute the login page:

LoginDialog* loginDialog = new LoginDialog(m_mainWindow);
connect(loginDialog, SIGNAL(acceptLogin(QString&,QString&,int&)), m_mainWindow, SLOT(slotAcceptUserLogin(QString&,QString&)));
loginDialog->exec();

But every time I get this error:

undefined reference to `LoginDialog::LoginDialog(QWidget*)'
collect2: error: ld returned 1 exit status

I have tried setting the

LoginDialog::LoginDialog(QWidget* parent) :
 QDialog(parent)

To:

LoginDialog::LoginDialog(QWidget* parent=0) :
 QDialog(parent)

But still the same error. I have searched online and saw several fixes for this issue. But none has worked for me. I have already put Q_OBJECT in my class. Already set default QWidget* parent value to 0, but nothing seemed to work.

Any idea how I should proceed with this?

Thanks in advance.

John
  • 83
  • 7
  • what is the "#include "formlogin.h""? Do you mean first code part? – Alex Oct 17 '17 at 09:36
  • @Alex, yes. The first code part. – John Oct 17 '17 at 09:37
  • @John Do not repeat the default argument (`= 0`) in the cpp. Not that it would not work, but it is at least error prone. – Benjamin T Oct 17 '17 at 09:39
  • @John Can you give more details about the compilation process? Maybe you did not compile the .cpp file? – Benjamin T Oct 17 '17 at 09:40
  • @HiI'mFrogatto, @Benjamin, I am working with a desktop application. I don't have any `.pro` file. or I can't find it. After I make any changes, I have to run `make` to check the code. Do you want me to paste the main.cpp file where the login page is called? – John Oct 17 '17 at 09:43
  • I think it may be include path issue. Please try to set path to the h file, like "include " – Alex Oct 17 '17 at 09:43
  • @John I think you don't compile your cpp file at all. That's why linker complains that it couldn't find that symbol in given object files. – frogatto Oct 17 '17 at 09:46
  • @Alex, I have tried `#include "gui/formlogin.h"`, `#include `, but didnt work. – John Oct 17 '17 at 09:50
  • @HiI'mFrogatto, I have already added the header file to my main.cpp file. Is there any other way to make sure the cpp gets compiled? – John Oct 17 '17 at 09:51
  • @John How do you compile the project? Please post your makefiles. – frogatto Oct 17 '17 at 09:59
  • @HiI'mFrogatto, yes I am an idiot. I forgot to add the cpp to the makefile list. I have added there now and trying to build it. Will post the result when I am done. Thanks a lot. – John Oct 17 '17 at 10:01
  • @HiI'mFrogatto, yes it's working perfectly now. Thanks :) – John Oct 17 '17 at 10:13
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Tadeusz Kopec for Ukraine Oct 17 '17 at 10:42

1 Answers1

0

This looks like a linker issue. Have you got a makefile to compile it and link it? If you just run make without this, it will not know what to link. The linker will need to link the object files for main.cpp, formlogin.cpp and the cpp generated by running moc on formlogin.h - as Froggatt said, using a .pro file is the easiest way to get a makefile generated for you to do all of this.

Ian4264
  • 307
  • 2
  • 6
  • umm, yes I have a makefile and I haven't linked anything there. I will add the reference to the file there and try again. Thanks. – John Oct 17 '17 at 09:54
  • Yes after adding the cpp file to the makefile list, it worked perfectly. – John Oct 17 '17 at 10:14