发现的信号未被检测到

时间:2016-04-04 07:24:34

标签: c++ qt c++11 qt5

我试图从班上发出信号finished()。但是,当我将信号连接到我的插槽时,它没有做任何事情。

我的班级' name为blend_install,我将其声明为blendinstaller并尝试将其连接到QEventLoop。

....
QEventLoop ac;
connect(&blendinstaller, SIGNAL(finished()), &ac, SLOT(quit()));

blendinstaller.show_progress();
blendinstaller.download(); // this will execute everything and in the end emit finished()

ac.exec();
....

download()功能:

current_prog = BLEND_INSTALL_NONE;
emit progress_changed(current_prog);

manager = new QNetworkAccessManager;

file_handler = new QFile(downloadTo);

file_handler->open(QFile::WriteOnly);
.... handle error .... // each of this (error handling) will emit finished() signal and return;

.... // each of this will represent the process of reporting event changes (for logging), emit a SIGNAL()

QNetworkRequest request;
request.setUrl(QUrl(downloadFrom));

reply = manager->get(request);
event = new QEventLoop;
connect(reply,SIGNAL(finished()),event,SLOT(quit()));
connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(downloadError(QNetworkReply::NetworkError)));
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(downloadProgressL(qint64,qint64)));


event->exec();

.... handle error ....

.... write reply.readAll() to file ....

....

// these are instruction for a custom QProcess instance
proc.setProgram(extractWith);
proc.setArguments(ar);
proc.setWorkingDirectory(downloadIn);

event = new QEventLoop;
connect(&proc,SIGNAL(finished(int)),event,SLOT(quit()));
connect(&proc,SIGNAL(error(QProcess::ProcessError)),this,SLOT(extractError(QProcess::ProcessError)));
connect(&proc,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(extractFinished(int,QProcess::ExitStatus)));

proc.start();
proc.open_console();

event->exec();

.... handle error ....

....

.... attempt to find output of QProcess (extract an archive) ....

.... handle error, output of QProcess not found ....

....

emit installed(installOn);
emit finished(); // the SIGNAL I want to get.

qDebug("It's finished installing!");

所以,TL; DR每个错误处理都会从函数返回但是也会发出finished()并且在函数结束时(假设没有错误)它会发出{{ 1}}。

它不会退出循环。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

download()方法存在的问题是,它已经是一个同步方法。您不需要此事件循环。您已经在download()方法中的事件循环中执行了所有操作。

旁注:而且您似乎有一些内存泄漏,因为您创建没有父级的QEventLoop并且永远不会删除它。

更新#1: 外部QEventLoop(finished())未处理您的ac事件,因为在QEventLoop开始处理finished()事件之前发出exec()信号。 作为一个丑陋的工作环境,您可以在download()之后使用排队的exec()(Qt :: QueuedConnection)调用调用QMetaObject::invokeMethod()(但我不推荐它)。

更新#2 这是一个小例子,当然不完美:P

class BlendDownloader
{
  Q_OBJECT

public:
  BlenDownloader() :
    _file(NULL)
  {
  }

  void download()
  {
    _file = new QFile("C:/myfile.blubb");

    QNetworkRequest req("your url here");
    QNetworkReply* reply = _mgr.get(req);
    QObject::connect(reply, SIGNAL(finished()), this, SLOT(onDownloadFinished()));
    // TODO: Also handle error callback here
  }

private slots:
  void onDownloadFinished()
  {
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
    reply->deleteLater();

    // Write response data to file.
    // Note: You might get problems with big files,
    // since this buffers the entire response of QNetworkReply
    // in internal buffer. It's better to use the "readyRead()"
    // signal and write incrementally.
    _file->write(reply->readAll());

    // Do your parsing stuff now and emit "finished()" at the end.
    // ... parsing, validation here ...

    // Clean up
    _file->close();
    delete _file;
    _file = NULL;

    emit finished();
  }

private:
  QNetworkManager _mgr;
  QFile* _file;
};