在visual studio上编译qt示例时发生链接错误

Link error while compiling qt example on visual studio

本文关键字:链接 错误 studio visual 编译 qt      更新时间:2023-10-16

我在用visual c++express 2010上的qt 4第二版书编译c++GUI编程中的qt示例时遇到了问题。由于qt visual studio加载项不适用于express edition,我只需添加库依赖项就可以自行配置它:qtmaind.lib QtCred4.lib QtGuid4.lib。此外,我还可以编译示例代码"你好,qt!"没有错误。我的项目包含两个.cpp文件和一个头文件:
findDialog.h:

#ifndef FINDDIALOG_H
#define FINDDIALOG_H
#include <QtGuiqdialog.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 <QtGuiQtGui>
#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 <QtGuiqapplication.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();
}

当我编译这个项目时,我得到了6个链接错误:

LNK2001:未解析的外部符号"public:virtual struct QMetaObject const*__thiscall findDialog::metaObject(void)const"(?metaObject@findDialog@@UBEPBUQMetaObject@@XZ)

LNK2001:未解析的外部符号"public:virtual void*__thiscall findDialog::qt_metacast(char const*)"(?qt_metacast@findDialog@@UAEPAXPBD@Z)

LNK2001:未解析的外部符号"public:virtual int__thiscall findDialog::qt_metacall(enum QMetaObject::Call,int,void**)"(?qt_metacall@findDialog@@UAEHW4Call@QMetaObject@@HPAPAX@Z)

LNK2001:未解析的外部符号"public:static struct QMetaObject const findDialog::staticMetaObject"(?staticMetaObject@findDialog@@2UQMetaObject@@B)

LNK2019:未解析的外部符号"protected:void __thiscall findDialog::findNext(class QString const&,enum Qt::CaseSensitivity)"(?findNext@findDialog@@IAEXABVQ字符串@@W4CaseSensitivity@Qt@@@Z) 在函数"private:void __thiscall findDialog::findClicked(void)"中引用(?findClicked@findDialog@@AAEXXZ)

LNK2019:未解析的外部符号"protected:void __thiscall findDialog::findPrevious(class QString const&,enum Qt::CaseSensitivity)"(?findPrevious@findDialog@@IAEXABVQ字符串@@W4CaseSensitivity@Qt@@@Z) 在函数"private:void __thiscall findDialog::findClicked(void)"中引用(?findClicked@findDialog@@AAEXXZ)

提前谢谢你,为我糟糕的英语感到抱歉。

由于您没有Qt Integration,我检查了我的一个Qt项目的设置。

FindDialog.hproperty页面上,将Item TypeC/C++ header更改为Custom Build Tool。按下Apply时,左侧会出现一个新的Custom Build Tool项目。展开它,在General中会找到Command Line,输入

"$(QTDIR)binmoc.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)includeQtCore" "-I$(QTDIR)includeQtGui" ".FindDialog.h" -o ".GeneratedFiles$(ConfigurationName)moc_$(InputName).cpp"

这是我发布版本的命令行。您应该根据您的配置进行更改。请记住将生成的cpp添加到您的项目中。

Custom Build Tool下,有一个名为Outputs的项目,它应该是

".GeneratedFiles$(ConfigurationName)moc_FindDialog.cpp" 

由于我可能仍然缺少一些东西,以下是vc项目文件中该文件的部分:

        <File
            RelativePath=".FindDialog.h"
            >
            <FileConfiguration
                Name="Release|Win32"
                >
                <Tool
                    Name="VCCustomBuildTool"
                    Description="Moc&apos;ing FindDialog.h..."
                    CommandLine="&quot;$(QTDIR)binmoc.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)includeQtCore&quot; &quot;-I$(QTDIR)includeQtGui&quot; &quot;.FindDialog.h&quot; -o &quot;.GeneratedFiles$(ConfigurationName)moc_$(InputName).cpp&quot;&#x0D;&#x0A;"
                    AdditionalDependencies="&quot;$(QTDIR)binmoc.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)binmoc.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)includeQtCore&quot; &quot;-I$(QTDIR)includeQtGui&quot; &quot;.FindDialog.h&quot; -o &quot;.GeneratedFiles$(ConfigurationName)moc_$(InputName).cpp&quot;&#x0D;&#x0A;"
                    AdditionalDependencies="&quot;$(QTDIR)binmoc.exe&quot;;.FindDialog.h"
                    Outputs="&quot;.GeneratedFiles$(ConfigurationName)moc_FindDialog.cpp&quot;"
                />
            </FileConfiguration>
        </File>

请注意,这是来自VS2008的vcproj

也许你可以根据起亚的诊断和的进一步信息做大量的工作来解决你的问题

  1. 成功的宣言
  2. 一个源(1)基于
  3. QT论坛上相当典型的帖子(总结:预计会有问题)

但所有这些工作都不会进一步提高你的知识/技能,比如一般的wrt编程、c++或qt。如果Visual Studio对您来说很重要,请投资一个专业使用的不受限制的版本,并安装外接程序,避免为不适合的用途配置工具的麻烦。否则,请安装QT Creator(请参阅(2);Qt Creator IDE和工具)。

链接错误来自Qt's Meta Object Compiler
简单地说,当你在类中编写Q_OBJECT宏时,它在类中定义了Qt处理事件所需的一些成员函数
Qt MOC将创建一个新的.cpp文件,并在其中写入这些函数的主体。
链接错误清楚地表明FindDilog的特定.cpp文件(名为moc_FindDialog.cpp)丢失。这意味着moc文件不是由Qt生成的
也许Visual Studio忘记调用Qt-Moc来生成.cpp文件。也许Visual Studio编译器没有编译它…

确保findDialog.h明确包含在.pro文件中。如果不是,请添加它,并确保在尝试构建项目之前再次运行qmake。