-1

I'm making a little GUI program using Qt creator, but I get stuck with two "unresolved externals" errors. Here are all of my code: (By the way, I following the book C++ GUI Programming with Qt4, second edition. This are covered in chapter 2)

I got five files in total: (The code are kinda long, so you can skip some and go directly to the end for my explanation.)

First, mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

finddialog.h:

#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include<QDialog>       

class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;

class FindDialog:public QDialog
{
    Q_OBJECT       
public:
    FindDialog(QWidget* parent=0);

signals:
    void findNext(const QString &str,Qt::CaseSensitivity cs);
    void findPrevious(const QString &str,Qt::CaseSensitivity cs);

private slots:
    void findClicked();
    void enableFindbuton(const QString& text);

private:
    QLabel* label;
    QLineEdit* lineEdit;
    QCheckBox* caseCheckBox;
    QCheckBox* backwardCheckBox;
    QPushButton* findButton;
    QPushButton* closeButton;

};
#endif

finddialog.cpp:

#include<QtGui>       

#include"finddialog.h"

FindDialog::FindDialog(QWidget* parent=0):QDialog(parent=0)
{
    label=new QLabel(tr("Find %what"));
    lineEdit=new lineEdit;
    label->setBuddy(lineEdit);

    caseCheckBox=new QCheckBox(tr("Match &case"));
    backwardCheckBox=new QCheckBox(tr("search &backward"));

    findButton=new QPushButton("&Find");
    findButton->setDefault(true);
    findButton->setDefault(false);

    closeButton=new QPushButton(tr("close"));


    connect(lineEdit,SIGNAL(textchanged(const QString &)),
            this,SLOT(enableFindbuton(const QString &));
    connect(findButton,SIGNAL(clicked()),
        this,SLOT(findClicked());
    connect(closeButton,SIGNAL(clicked()),
        this,SLOT(close());

    QHBoxLayout* topLeftLayout=new QHBoxLayout;
    topLeftLayout->addWidget(label);
    topLeftLayout->addWidget(lineEdit);

    QVBoxLayout* leftLayout=new QVBoxLayout;
    leftLayout->addLayout(topLeftLayout);
    leftLayout->addWidget(caseCheckBox);
    leftLayout->addWidget(backwardCheckBox);

    QVBoxLayout* rightLayout=new QVBoxLayout;
    rightLayout->addWidget(findButton);
    rightLayout->addWidget(closeButton);
    rightLayout->addStretch();   //what the hell is this function?

    QHBoxLayout* mainlayout=new QHBoxLayout;
    mainlayout->addLayout(leftLayout);
    mainLayout->addLayout(rightLayout);

    setWindowTitle(tr("Find"));
    setFixedHeight(sizeHint().height());  

    }

void FindDialog::findClicked()
{
    QString text=lineEdit->text();
    Qt::CaseSensitivity cs=caseCheckBox->isChecked()?   Qt::CaseSensitive:Qt::CaseInsensitive;

    if(backwardCheckBox->isChecked()){
        emit findPrevious(text,cs);
    }else{
        emit findNext(text,cs);
    }
}     

void FindDialog::enableFindbuton(const QString &text)
{
    findButton->setEnabled(!text.isEmpty());
}

main.cpp:

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

class FindDialog;
int main(int argc,char*argv[])
{
    QApplication app(argc,argv);
    MainWindow w;
    w.show();
    FindDialog* dialog=new FindDialog;
    dialog->show();

    return app.exec();
}

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QObject>

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

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

I am making a dialog window exactly like this: enter image description here so that is the whole main structure of my code. Hope you can understand it. I'm so sorry that it is that long.

I didn't use the "qmake" and "make" as the author did in the book. I directly use the Qt creator. And then the whole thing mess up.... The two error messages look like this:

main.obj:-1: error: LNK2019: unresolved external symbol "public: __cdecl    FindDialog::FindDialog(class QWidget *)" (??0FindDialog@@QEAA@PEAVQWidget@@@Z) referenced in function main

debug\test2.exe:-1: error: LNK1120: 1 unresolved externals
Alex
  • 293
  • 2
  • 10
  • Can you please post the full error messages that you see? "unresolved externals" sounds like a linker error. – Philipp Claßen Apr 26 '15 at 13:13
  • @PhilippClaßen get it – Alex Apr 26 '15 at 13:26
  • @PhilippClaßen I have post all the error message I got. – Alex Apr 26 '15 at 13:29
  • Btw, I saw your comment about `addStretch()`. It "pads" the end of the layout so previously added widgets/layouts don't keep expanding. Once you've gotten it to work, try commenting out that line to see the difference. – jonspaceharper Apr 26 '15 at 13:52
  • And one more tip: you've created a FindDialog instance using `new` without giving it a parent. Change that line in main.cpp to read "FindDialog dialog;" to avoid memory leaks. – jonspaceharper Apr 26 '15 at 13:54
  • @walkerlala: I think we've covered your original question. I threw in details about how to fix your other issues in my answer, but this really should be posted as a new question. – jonspaceharper Apr 26 '15 at 14:24

2 Answers2

1

From the Build menu, select "Run qmake". Then clean and rebuild (not build) your project. QtCreator isn't smart about doing this for you when new classes are created or moc-impacting changes are made (adding slots, etc.). When in doubt with linker errors, run qmake.

You have some issues with forward declarations and missing #include statements. See What are forward declarations in C++? for info on why this breaks stuff and when to use it.

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

//removed forward declaration of FindDialog
int main(int argc,char*argv[])
{
    QApplication app(argc,argv);
    MainWindow w;

    FindDialog dialog; //removed usage of new
    w.show();
    dialog.show();
    return app.exec();
}

And in your finddialog.cpp:

//#include <QtGui>
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
Community
  • 1
  • 1
jonspaceharper
  • 4,207
  • 2
  • 22
  • 42
  • This is because of other bugs. I noted you have default arguments in your constructor implementation, for example. They're only turning up now because the compiler has gotten past being confused about your moc files. You've also forward declared FindDialog after including finddialog.h. – jonspaceharper Apr 26 '15 at 13:47
  • Then how to fix that? – Alex Apr 26 '15 at 13:53
  • Remove the forward declaration line immediately before `main()`. – jonspaceharper Apr 26 '15 at 13:56
  • which forward declaration line? – Alex Apr 26 '15 at 14:01
  • This is a separate question, but: in your finddialog.cpp, you need to add `#include` statements for all of your forward declared classes from finddialog.h. So: `#include ` at the top of findialog.cpp and so forth. – jonspaceharper Apr 26 '15 at 14:09
  • I do. but there is still error like "use of undentified type 'QLabel' " what should I do next? – Alex Apr 26 '15 at 14:11
  • Run qmake again and rebuild. – jonspaceharper Apr 26 '15 at 14:14
  • Can I send you the source code from the book and you check if there is any mistake in the code? Or can you try it for me? I don't know if I get the whole thing right. So could you please check it for me? If you may, this is my email address: awhitetshirt@163.com. Send me an email and then I can reply you. – Alex Apr 26 '15 at 14:35
0

It appears that finddialog.h doesn't contain the definition of the function FindDialog.

In this case you need to link the appropriate library (containing the definition of FindDialog), with your program