2016-04-04 12 views
0

私のクラスからシグナルfinished()を放出しようとしました。しかし、私がスロットに信号を接続しているとき、何もしませんでした。放射されたシグナルが検出されない

私のクラスの名前は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()を放出し、関数の最後に(エラーがないと仮定します)それはfinished()を放出するでしょう。

ループを終了しません。

+2

それは罰金に見えるん:

ここで更新#2 はもちろん、完璧ではない小さな例、です。 'download()'実装を投稿できますか?あなたの 'download()'メソッドが 'finished()'シグナルをあまりにも早く放出することは想像できません。より良いと言った:それは全くそれから呼び出されるべきではない。通常、ある種のプライベートスロット 'onDownloadComplete()'は 'finished()'シグナルを出力します。 – mfreiholz

+0

@mfreiholz私はそれをアップロードしました。私はあなたの提案を試してみるでしょう... –

+0

"それはインストールが完了しました!"しかし、まだ 'finished()'シグナルは出ません。 –

答えて

1

download()メソッドの問題は、すでに同期メソッドであるということです。このイベントループは必要ありません。 download()メソッド内のイベントループ内のすべてを既に実行しています。

サイドノート:そして、あなたは親なしでQEventLoopを作成し、決してそれを削除しないので、いくつかのメモリリークがあるようです。

UPDATE#1: QEventLoopもexec()でイベントを処理するために開始する前にfinished()信号が放射されますので、あなたのfinished()イベントは、外側QEventLoop(ac)によって処理されていません。 の後にexec()の後にQMetaObject::invokeMethod()(Qt :: QueuedConnection)コールがキューされていても、醜いワークアラウンドが発生する可能性があります(ただし、お勧めしません)。 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; 
}; 
+0

これは ' 'QEventLoop'の中に' QEventLoop'があります。なぜなら、すべてが終了するまで待つ必要があるからです。しかし、メモリリークのためかもしれません。クラスのプライベートセクションでQEventLoopを宣言しましたが、それは悪いですか? –

+0

@TitoNoveliantoなぜ「終了」信号を出すときにすべてが終了するまで待つ必要がありますか? 'done'シグナルを' loop-> exec'の後にやっているスロットに接続してください(これはあなたがやっているようです)。 – thuga

+0

私の答えを小さな例(更新#2)で更新しました – mfreiholz

関連する問題