2011-02-07 2 views
1

私は最近、約2ヶ月前に書いた大きなモノリシックのオーディオプレーヤーアプリケーションをモジュール化するという面倒なプロセスを開始しました。スタンドアロンクラスにリファクタリングした後、QNetworkRequest(HTTP GET)が起動しない

このプロセスは、ScrobbleMedia(再生可能なトラックに関する情報をlast.fmに提出するというHTTP要求を予測するほどには十分ではない)が、もはやネットワーク要求をしていないように見えます。

ただし、QNetworkAccessManagerインスタンス/ QNetworkRequestに渡されるQUrlオブジェクトは正しく構築されています。

比較のため、コードの機能的なMercurialリビジョンはBitBucketにあります。

ScrobbleMedia方法は、現在、リファクタリングした後、次のようになります。

#include "scrobblemedia.h" 

#include <QDebug> 
#include <cstdio> 

ScrobbleMedia::ScrobbleMedia(QString asUsername, QString asPassword, 
         QString asArtist, QString asTrack, QString asAlbum) 
{ 

    QString KEndPointURL = "http://lastfmstats.livefrombmore.com/universalscrobbler/scrobble.php"; 
    QUrl iScrobbleEndPoint(KEndPointURL); 

     QNetworkAccessManager *iScrobbleDispatcher = new QNetworkAccessManager(this); 


iScrobbleEndPoint.addQueryItem("submissionType","track"); 
iScrobbleEndPoint.addQueryItem("username", asUsername); 
iScrobbleEndPoint.addQueryItem("password", asPassword); 
iScrobbleEndPoint.addQueryItem("artist", asArtist); 
iScrobbleEndPoint.addQueryItem("track", asTrack); 
iScrobbleEndPoint.addQueryItem("album", asAlbum); 
iScrobbleEndPoint.addQueryItem("number","1"); 
iScrobbleEndPoint.addQueryItem("duration","200"); 

iScrobbleDispatcher->get(QNetworkRequest(iScrobbleEndPoint)); 
connect(iScrobbleDispatcher, SIGNAL(finished(QNetworkReply*)), 
SLOT(replyFinished(QNetworkReply*))); 

// QString Outside = iScrobbleEndPoint.toEncoded(); 

qDebug() << "Received: " + 
    asUsername + " " + 
    asPassword + " " + 
    asArtist + " " + 
    asTrack + " " + 
     asAlbum; 

qDebug() << iScrobbleEndPoint.toString(); 

} 

ScrobbleMedia::~ScrobbleMedia() { 

} 

関連するヘッダファイルは以下のようになります。私は、現在のバージョンのMinGWのビルドに対するアプリケーション自体を構築しています

#ifndef SCROBBLEMEDIA_H 
#define SCROBBLEMEDIA_H 

#include <QString> 
#include <QtNetwork> 
#include <QUrl> 
#include <QNetworkAccessManager> 



class ScrobbleMedia : public QObject 
{ 
    Q_OBJECT; 


private: 

public: 

    ScrobbleMedia(QString asUsername, QString asPassword, QString asArtist, QString asTrack, QString asAlbum); 
    ~ScrobbleMedia(); 

}; 

#endif // SCROBBLEMEDIA_H 

Windows 7 x86-64でのQtライブラリ(Qt SDK 2010.05の一部として含まれています)4.7.0。

ご協力いただければ幸いです。

ありがとうございます。

+1

2つの質問:なぜQ_OBJECTマクロの後にセミコロンがあるのですか?ヘッダーにreplyFinished()スロットが宣言されていないのはなぜですか? Windowsの場合は、CONFIG + = console qmakeオプションを使用してプロジェクトを再コンパイルしてください。実行時のQt警告(「no such slot」メッセージなど)が表示されます。 –

+0

ありがとう、セルゲイ。私は今夜​​コードを更新し、何が起こったのかを教えてくれます(Qtのツールチェインが現時点では便利ではないため)。セミコロンは習慣的で、違いを生むかどうかは分かりませんでした。 – Tyson

+1

@Tyson、またあなたのQt SDKのバージョンを提供する必要があります。古いバージョンのQtではQNAMとfinished()シグナルに多くの問題があります。 – Johnny

答えて

0

多くの異なる情報源(ほとんどが矛盾していました)を読んだ後、私は以下の結果が実際の解決策であることを発見しました。デバッグ出力には影響がないようです操作(Object::connect: No such signal QNetworkReplyImpl::finished(QNetworkReply*) in ../AudioPlayer/scrobblemedia.cpp:29):

scrobblemedia.cpp

において:

#include "scrobblemedia.h" 

#include <QDebug> 
#include <cstdio> 

ScrobbleMedia::ScrobbleMedia(QString asUsername, QString asPassword, 
          QString asArtist, QString asTrack, QString asAlbum) 
{ 

    QByteArray iDataSink; 
    QEventLoop iLoop; 

    QString KEndPointURL = "http://lastfmstats.livefrombmore.com/universalscrobbler/scrobble.php"; 
    QUrl iScrobbleEndPoint(KEndPointURL); 

    iScrobbleEndPoint.addQueryItem("submissionType","track"); 
    iScrobbleEndPoint.addQueryItem("username", asUsername); 
    iScrobbleEndPoint.addQueryItem("password", asPassword); 
    iScrobbleEndPoint.addQueryItem("artist", asArtist); 
    iScrobbleEndPoint.addQueryItem("track", asTrack); 
    iScrobbleEndPoint.addQueryItem("album", asAlbum); 
    iScrobbleEndPoint.addQueryItem("number","1"); 
    iScrobbleEndPoint.addQueryItem("duration","200"); 

    QNetworkAccessManager iScrobbleDispatcher; 
    QNetworkRequest iScrobbleRequest(iScrobbleEndPoint); 
    QNetworkReply *iScrobbleReply = iScrobbleDispatcher.get(iScrobbleRequest); 

    QObject::connect(iScrobbleReply, SIGNAL(finished(QNetworkReply*)), &iLoop, 
    SLOT(quit())); 

    iDataSink = iScrobbleReply->readAll(); 

    qDebug() << "Received: " + asUsername + " " + asPassword + " " + asArtist + " " + asTrack + " " + asAlbum; 

    qDebug() << iScrobbleEndPoint.toString(); 

    iLoop.exec(); 
} 

ScrobbleMedia::~ScrobbleMedia() { 

} 

void ScrobbleMedia::replyFinished(QNetworkReply*) { 

} 

void ScrobbleMedia::reallyDone() { 

    qDebug() << "We've probably successfully Scrobbled..."; 
} 

scrobblemedia.hにおいて:

#ifndef SCROBBLEMEDIA_H 
#define SCROBBLEMEDIA_H 

#include <QString> 
#include <QtNetwork> 
#include <QUrl> 
#include <QNetworkAccessManager> 



class ScrobbleMedia : public QObject 
{ 
    Q_OBJECT 


private: 


public: 

    ScrobbleMedia(QString asUsername, QString asPassword, QString asArtist, QString asTrack, QString asAlbum); 
    ~ScrobbleMedia(); 

private slots: 
    void replyFinished(QNetworkReply*); 
    void reallyDone(); 

}; 

#endif // SCROBBLEMEDIA_H 

誰もが助けてくれてありがとう。

このコードは、今後他の人にとって有用なテンプレートとして役立ちます。

+0

どこに本当に本当にスロット()が呼ばれていますか?私はコードでそれを見ません。なぜあなたはイベントループが必要ですか?マルチスレッドアプリケーションでない場合は、別のイベントループを使用することは少なくとも不必要であるか、あるいは危険でさえありません。最後に、あなたの問題は「化粧品」ではありません。これは、iScrobbleReplyの存在しないシグナル 'finished(QNetworkReply *)'に接続しようとしているためです。パラメータなしのfinished()シグナルしかありません。 QNetworkReply *パラメーターを持つfinished()スロットを持つQNetworkAccessManagerです。だからあなたのquit()メソッドは決して呼び出されません。 –

+0

reallyDone()はどこからでも呼び出されません。以前の試みから残っているだけです。イベントループのアイデアはhttp://stackoverflow.com/questions/2572985/how-can-i-use-qt-to-get-html-code-of-the-redirected-pageで提案されていて、私の場合。 – Tyson

+0

これを念頭に置いて、私は 'reallyDone()'を削除し、それをスタブ実装するだけでなく、 'void finished(QNetworkReply *)'を定義しました。コード自体はまだ動作しています(私はWiresharkでHTTP要求を見ることができます)。しかし、 "底なしスロット"の問題をきれいに処理することは、後で行うことです。 – Tyson

関連する問題