1
votes

I have a problem in compiling a qt example from c++ GUI programming with qt 4 second edition book on visual c++ express 2010.Since qt visual studio add-in doesn't work with express edition , I configured it by myself by just adding library dependencies: qtmaind.lib QtCored4.lib QtGuid4.lib .Also I can compile a sample code 'Hello,Qt!' without error. My project contains two .cpp files and a header file:
findDialog.h:

#ifndef FINDDIALOG_H
#define FINDDIALOG_H

#include <QtGui\qdialog.h>
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 enableFindButton(const QString& text);
private:
    QLabel* label;
    QLineEdit* lineEdit;
    QCheckBox* caseCheckBox;
    QCheckBox* backwardCheckBox;
    QPushButton* findButton;
    QPushButton* closeButton;
};
#endif

findDialog.cpp:

#include <QtGui\QtGui>
#include "findDialog.h"


findDialog::findDialog(QWidget* parent) : QDialog(parent)
{
    label = new QLabel(tr("Find &what:"));
    lineEdit = new QLineEdit;
    label->setBuddy(lineEdit);

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

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

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

    connect(lineEdit , SIGNAL(textChanged(const QString&)) , this , SLOT(enableFindButton(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();

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

    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::enableFindButton(const QString& text)
{
    findButton->setEnabled(!text.isEmpty());
}

main.cpp:

#include <QtGui\qapplication.h>
#include <iostream>
#include "findDialog.h"



int main(int argc , char* argv[])
{
    QApplication app(argc , argv);
    findDialog* dialog = new findDialog;
    dialog->show();
    return app.exec();
}

When I compile this project , I get 6 link errors :

LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall findDialog::metaObject(void)const " (?metaObject@findDialog@@UBEPBUQMetaObject@@XZ)

LNK2001: unresolved external symbol "public: virtual void * __thiscall findDialog::qt_metacast(char const *)" (?qt_metacast@findDialog@@UAEPAXPBD@Z)

LNK2001: unresolved external symbol "public: virtual int __thiscall findDialog::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@findDialog@@UAEHW4Call@QMetaObject@@HPAPAX@Z)

LNK2001: unresolved external symbol "public: static struct QMetaObject const findDialog::staticMetaObject" (?staticMetaObject@findDialog@@2UQMetaObject@@B)

LNK2019: unresolved external symbol "protected: void __thiscall findDialog::findNext(class QString const &,enum Qt::CaseSensitivity)" (?findNext@findDialog@@IAEXABVQString@@W4CaseSensitivity@Qt@@@Z) referenced in function "private: void __thiscall findDialog::findClicked(void)" (?findClicked@findDialog@@AAEXXZ)

LNK2019: unresolved external symbol "protected: void __thiscall findDialog::findPrevious(class QString const &,enum Qt::CaseSensitivity)" (?findPrevious@findDialog@@IAEXABVQString@@W4CaseSensitivity@Qt@@@Z) referenced in function "private: void __thiscall findDialog::findClicked(void)" (?findClicked@findDialog@@AAEXXZ)

Thank you in advance and sorry for my bad english.

4
Do you generated moc_findDialog.cpp?werewindle

4 Answers

1
votes

Perhaps you can solve your problem with a lot of work based on Kia.celever's diagnosis and further info from

  1. a claim of success
  2. one source (1) is based on
  3. fairly typical posting in QT forum (summary: expect problems)

But all this work won't further your knowledge/skills wrt programming in general, c++, or qt. If Visual Studio is important for you, invest in an unrestricted version for professional use and install the add-in and avoid the hassle of configuring a tool for a use it is not meant for. Otherwise, install QT-Creator (see (2); Qt Creator IDE and tools).

2
votes

As you do not have Qt Integration, I checked one of my Qt project for the settings.

On the property page of FindDialog.h, change Item Type from C/C++ header to Custom Build Tool. When press Apply, a new Custom Build Tool Item would appear on the left. Expand it, in General you will find Command Line, enter

"$(QTDIR)\bin\moc.exe"   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_DLL  "-I.\GeneratedFiles" "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" ".\FindDialog.h" -o ".\GeneratedFiles\$(ConfigurationName)\moc_$(InputName).cpp"

This is my command line for a release build. You should change it according to your configuration. Remember to added the generated cpp to your project.

Under Custom Build Tool, there's an item called Outputs, which should be

".\GeneratedFiles\$(ConfigurationName)\moc_FindDialog.cpp" 

As I may be still missing something, the following is the section for this file in vc's project file:

        <File
            RelativePath=".\FindDialog.h"
            >
            <FileConfiguration
                Name="Release|Win32"
                >
                <Tool
                    Name="VCCustomBuildTool"
                    Description="Moc&apos;ing FindDialog.h..."
                    CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_DLL  &quot;-I.\GeneratedFiles&quot; &quot;-I$(QTDIR)\include&quot; &quot;-I.\GeneratedFiles\$(ConfigurationName)\.&quot; &quot;-I.&quot; &quot;-I$(QTDIR)\include\QtCore&quot; &quot;-I$(QTDIR)\include\QtGui&quot; &quot;.\FindDialog.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_$(InputName).cpp&quot;&#x0D;&#x0A;"
                    AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\FindDialog.h"
                    Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_FindDialog.cpp&quot;"
                />
            </FileConfiguration>
            <FileConfiguration
                Name="Debug|Win32"
                >
                <Tool
                    Name="VCCustomBuildTool"
                    Description="Moc&apos;ing FindDialog.h..."
                    CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot;   -DUNICODE -DWIN32 -DQT_THREAD_SUPPORT -DQT_CORE_LIB -DQT_GUI_LIB  &quot;-I.\GeneratedFiles&quot; &quot;-I$(QTDIR)\include&quot; &quot;-I.\GeneratedFiles\$(ConfigurationName)\.&quot; &quot;-I.&quot; &quot;-I$(QTDIR)\include\QtCore&quot; &quot;-I$(QTDIR)\include\QtGui&quot; &quot;.\FindDialog.h&quot; -o &quot;.\GeneratedFiles\$(ConfigurationName)\moc_$(InputName).cpp&quot;&#x0D;&#x0A;"
                    AdditionalDependencies="&quot;$(QTDIR)\bin\moc.exe&quot;;.\FindDialog.h"
                    Outputs="&quot;.\GeneratedFiles\$(ConfigurationName)\moc_FindDialog.cpp&quot;"
                />
            </FileConfiguration>
        </File>

Note this is from a vcproj for VS2008.

1
votes

The link errors are coming from Qt's Meta Object Compiler.
Simply when you write Q_OBJECT macro in a class, It defines some member functions in the class which are needed by Qt to handle events....
Qt MOC will create a new .cpp file and write those function's body in it.
Link errors clearly show that specific .cpp file for the FindDilog (named moc_FindDialog.cpp) is missing. Which means the moc file is not generated by Qt.
Maybe Visual Studio has forgot to call Qt Moc to generate .cpp file. and maybe Visual Studio compiler is not compiling it...

0
votes

Make sure findDialog.h is explicitly included in your .pro file. If it wasn't, add it and make sure to run qmake again before trying to build your project.