【问题标题】:Link error while compiling qt example on visual studio在 Visual Studio 上编译 qt 示例时出现链接错误
【发布时间】:2012-02-01 15:40:31
【问题描述】:

我在编译 c++ GUI programming with qt 4 second edition book on visual c++ express 2010 中的 qt 示例时遇到问题。由于 qt Visual Studio 插件不适用于 express edition ,我自己通过添加库依赖项来配置它: qtmaind.lib QtCored4.lib QtGuid4.lib 。我还可以编译示例代码“你好,Qt!”没有错误。 我的项目包含两个 .cpp 文件和一个头文件:
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();
}

当我编译这个项目时,我得到 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:在函数“私有:void __thiscall findDialog::findClicked(void)”(?findClicked@findDialog@@AAEXXZ)

LNK2019:在函数“私有:void __thiscall findDialog::findClicked(void)”(?findClicked@findDialog@@AAEXXZ)

提前谢谢你,对不起我的英语不好。

【问题讨论】:

  • 你生成 moc_findDialog.cpp 了吗?

标签: c++ visual-studio-2010 qt


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    由于您没有 Qt 集成,因此我检查了我的一个 Qt 项目的设置。

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

    "$(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"
    

    这是我发布版本的命令行。您应该根据您的配置更改它。记得将生成的 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)\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>
    

    请注意,这是来自 VS2008 的 vcproj

    【讨论】:

    • 不,它仍然有链接错误。还有一个警告:警告 MSB8018:没有为项目“findDialog.h”指定输出。它的自定义构建命令将被跳过。
    • @Arman-aegit:我想我最好将“.h”部分放在答案中......,Custom Build Step下有一个Output属性
    【解决方案3】:

    也许您可以根据 Kia.celever 的诊断和来自的更多信息进行大量工作来解决您的问题

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

    但所有这些工作不会进一步提高您在一般编程、c++ 或 qt 方面的知识/技能。如果 Visual Studio 对您很重要,请购买一个用于专业用途的无限制版本并安装加载项,并避免为不适合的用途配置工具的麻烦。否则,安装 QT-Creator(参见 (2);Qt Creator IDE and tools)。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 重新创建 Visual Studio 项目!
      猜你喜欢
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      相关资源
      最近更新 更多