2011-02-07 4 views
1

최근에 약 2 개월 전에 썼던 대형 모노 리식 오디오 플레이어 응용 프로그램을 모듈화하는 지루한 프로세스가 시작되었습니다.독립 실행 형 클래스로 리팩토링 한 후 QNetworkRequest (HTTP GET)가 실행되지 않습니다.

(ScrobbleMedia - 재생 트랙에 대한 정보를 제출할 HTTP 요청을 예측할 수있을 정도로 last.fm으로 만드는) 방법 중 하나가 더 이상 네트워크 요청을하지 않는 것으로 보입니다.

그러나 QNetworkAccessManager 인스턴스/QNetworkRequest로 전달되는 QUrl 개체가 올바르게 빌드되고 있습니다.

코드의 기능적 수정 버전은 BitBucket입니다.

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 

: 같은

#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() { 

} 

연관된 헤더 파일이 보인다 Windows 7 x86-64에서의 Qt 라이브러리 (Qt SDK 2010.05의 일부로 포함) 4.7.0.

도움을 주시면 감사하겠습니다.

미리 감사드립니다.

+1

두 가지 질문 : 왜 Q_OBJECT 매크로 뒤에 세미콜론이 있습니까? replyFinished() 슬롯이 헤더에 선언되지 않은 이유는 무엇입니까? Windows 사용자 인 경우 CONFIG + console qmake 옵션을 사용하여 프로젝트를 다시 컴파일하면 런타임에 Qt 경고 (예 : "슬롯이 없음"메시지)를 볼 수 있습니다. –

+0

고마워요, 세르게이. 오늘 밤에 코드를 업데이트하고 어떤 일이 일어 났는지 알려줄 것입니다. (Qt toolchain을 지금 당장 가지고 있지 않기 때문에) 세미콜론은 습관적이었고, 차이를 만들지는 확실하지 않았습니다. – 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

정확히 어디에서 reallyDone() 슬롯이 호출됩니까? 나는 코드에서 그것을 보지 못했다. 왜 이벤트 루프가 필요한가요? 멀티 스레딩 응용 프로그램이 아니라면 별도의 이벤트 루프를 사용하는 것이 적어도 불필요하거나 위험 할 수 있습니다. 그리고 마지막으로, 귀하의 문제는 "화장품"이 아닙니다. 당신은 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

관련 문제