QT: неразрешенный внешний символ при попытке получить исходный код веб-страницы

Я начал разработку с Qt и пытаюсь получить исходный код веб-страницы. Вот что у меня есть:

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QString>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QUrl>


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

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

/**/

class GetHTMLSource : public QObject
{
Q_OBJECT

public:
    GetHTMLSource();
    void GetSource();

public slots:
    void GetDone(QNetworkReply*);

private:
    QNetworkAccessManager* NetManager;
};


GetHTMLSource::GetHTMLSource()
{
    NetManager = new QNetworkAccessManager(this);

    connect(NetManager, SIGNAL(finished(QNetworkReply*)),
         this, SLOT(GetDone(QNetworkReply*)));

}

void GetHTMLSource::GetSource()
{
    NetManager->get(QNetworkRequest(QUrl("http://stackoverflow.com")));
}

void GetHTMLSource::GetDone(QNetworkReply* ReplyIn)
{

    QByteArray DataIn=ReplyIn->readAll();
    QString DataString(DataIn);

    //process str any way you like!

}

/**/

void MainWindow::on_pushButton_clicked()
{
    GetHTMLSource Test;
    Test.GetSource();
}

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 slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

.pro

QT       += core gui

TARGET = TestGetPageSource
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

QT += network

Ошибки бывают:

mainwindow.obj: -1: ошибка: LNK2001: неразрешенный внешний символ "public: виртуальная структура QMetaObject const * __thiscall GetHTMLSource :: metaObject (void) const" (? metaObject @ GetHTMLSource @@ UBEPBUQMetaObject @@ XZ)

mainwindow.obj: -1: ошибка: LNK2001: неразрешенный внешний символ "public: virtual void * __thiscall GetHTMLSource :: qt_metacast (char const *)" (? qt_metacast @ GetHTMLSource @@ UAEPAXPBD @ Z)

mainwindow.obj: -1: ошибка: LNK2001: неразрешенный внешний символ "public: virtual int __thiscall GetHTMLSource :: qt_metacall (enum QMetaObject :: Call, int, void * *)" (? qt_metacall @ GetHTMLSource @@ UAEHW4Call @ QMetaObject @ QMetaObject HPAPAX @ Z)


person dj8000    schedule 07.11.2012    source источник
comment
быстрое и грязное решение: добавьте #include "mainwindow.moc" в конец файла mainwindow.cpp   -  person Kamil Klimek    schedule 08.11.2012


Ответы (2)


Обычно, если вы создаете классы, производные от QObject, вы должны помещать их в отдельные заголовочные и исходные файлы.

Итак, один файл .h и один файл .cpp для одного класса.

person MichK    schedule 07.11.2012
comment
@ dj8000 Вы не забыли добавить GetHTMLSource.h и GetHTMLSource.cpp в свой файл .pro? Ваши ошибки возникают из-за того, что компилятор метаобъектов Qt (moc) не работает на GetHTMLSource. - person RA.; 08.11.2012
comment
Да, он был добавлен в ИСТОЧНИКИ и ЗАГОЛОВКИ автоматически. Ошибки все еще возникают. - person dj8000; 08.11.2012
comment
Это не правда. Вы также можете поместить классы на основе QObject в файлы cpp - person Kamil Klimek; 08.11.2012
comment
@KamilKlimek Конечно, можете, но для этого вы должны включить файл, сгенерированный moc, в ваш cpp. Таким образом, общее правило - разделить производный класс QObject на файлы .h и .cpp. - person MichK; 08.11.2012
comment
@MichK Я бы не стал заходить так далеко, что общее правило - разделять объекты QObject на файлы h / cpp. Поместите свой класс там, где вам нужно. Если вам нужно скрыть некоторые детали реализации, поместите их в файл .cpp и включите то, что вам нужно. - person Kamil Klimek; 09.11.2012

Исправил сам. Конечно, это была моя глупая ошибка.

В определении класса:

public slots:
    void GetDone(QNetworkReply*);

не соответствовал фактической функции:

void GetHTMLSource::GetDone(QNetworkReply* ReplyIn)
{ ... }

Однако перемещение его в отдельные файлы .h и .cpp, вероятно, помогло.

person dj8000    schedule 08.11.2012