我正在尝试将工作代码集成到我的程序中,但是在编译时我收到了标题上显示的错误。这是代码:
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
****************************************************************************/
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QSslError>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <stdio.h>
QT_BEGIN_NAMESPACE
class QSslError;
QT_END_NAMESPACE
QT_USE_NAMESPACE
class DownloadManager: public QObject
{
Q_OBJECT
QNetworkAccessManager manager;
QList<QNetworkReply *> currentDownloads;
public:
DownloadManager();
~DownloadManager() = 0;
void doDownload(const QUrl &url);
QString saveFileName(const QUrl &url);
bool saveToDisk(const QString &filename, QIODevice *data);
public slots:
void execute();
void downloadFinished(QNetworkReply *reply);
void sslErrors(const QList<QSslError> &errors);
};
DownloadManager::DownloadManager()
{
connect(&manager, SIGNAL(finished(QNetworkReply*)),
SLOT(downloadFinished(QNetworkReply*)));
}
DownloadManager::~DownloadManager()
{}
void DownloadManager::doDownload(const QUrl &url)
{
QNetworkRequest request(url);
QNetworkReply *reply = manager.get(request);
#ifndef QT_NO_SSL
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(sslErrors(QList<QSslError>)));
#endif
currentDownloads.append(reply);
}
QString DownloadManager::saveFileName(const QUrl &url)
{
QString path = url.path();
QString basename = QFileInfo(path).fileName();
if (basename.isEmpty())
basename = "download";
if (QFile::exists(basename)) {
// already exists, don't overwrite
int i = 0;
basename += '.';
while (QFile::exists(basename + QString::number(i)))
++i;
basename += QString::number(i);
}
return basename;
}
bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data)
{
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
fprintf(stderr, "Could not open %s for writing: %s\n",
qPrintable(filename),
qPrintable(file.errorString()));
return false;
}
file.write(data->readAll());
file.close();
return true;
}
void DownloadManager::execute()
{
QStringList args = QCoreApplication::instance()->arguments();
args.takeFirst(); // skip the first argument, which is the program's name
if (args.isEmpty()) {
printf("Qt Download example - downloads all URLs in parallel\n"
"Usage: download url1 [url2... urlN]\n"
"\n"
"Downloads the URLs passed in the command-line to the local directory\n"
"If the target file already exists, a .0, .1, .2, etc. is appended to\n"
"differentiate.\n");
QCoreApplication::instance()->quit();
return;
}
foreach (QString arg, args) {
QUrl url = QUrl::fromEncoded(arg.toLocal8Bit());
doDownload(url);
}
}
void DownloadManager::sslErrors(const QList<QSslError> &sslErrors)
{
#ifndef QT_NO_SSL
foreach (const QSslError &error, sslErrors)
fprintf(stderr, "SSL error: %s\n", qPrintable(error.errorString()));
#else
Q_UNUSED(sslErrors);
#endif
}
void DownloadManager::downloadFinished(QNetworkReply *reply)
{
QUrl url = reply->url();
if (reply->error()) {
fprintf(stderr, "Download of %s failed: %s\n",
url.toEncoded().constData(),
qPrintable(reply->errorString()));
} else {
QString filename = saveFileName(url);
if (saveToDisk(filename, reply))
printf("Download of %s succeeded (saved to %s)\n",
url.toEncoded().constData(), qPrintable(filename));
}
currentDownloads.removeAll(reply);
reply->deleteLater();
if (currentDownloads.isEmpty())
// all downloads finished
QCoreApplication::instance()->quit();
}
//int main(int argc, char **argv)
//{
// QCoreApplication app(argc, argv);
// DownloadManager manager;
// QTimer::singleShot(0, &manager, SLOT(execute()));
// app.exec();
//}
//#include "main.moc"
在上面的代码中,我删除了main()
(我将使用该类)和include "main.moc"
(这会导致找不到错误)。我还添加了析构函数以防万一。
这是QtCreator中的项目文件:
QT += widgets core network
CONFIG += console
CONFIG -= app_bundle
SOURCES = main.cpp \
gos.cpp \
download.cpp
HEADERS = gos.h
QMAKE_PROJECT_NAME = GoS
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tutorials/addressbook/part7
INSTALLS += target
simulator: warning(This example might not fully work on Simulator platform)
我错过了什么?
答案 0 :(得分:2)
代码是头文件(.h)还是源文件(.cpp)?从QObject进行子类化时,moc取决于标题中的类定义。
将类定义从download.cpp拆分为download.h并将其添加到HEADERS变量中。请记住make distclean
,然后再次调用qmake以获得干净的构建。
答案 1 :(得分:2)
由于main.cpp
文件包含Q_OBJECT
宏,因此您需要在源文件的末尾生成main.moc
个文件并#include "main.moc"
。
实际上,qmake
应该自行处理,但是在添加新的qmake
行然后重新构建之后,您需要为项目重新运行#include
。