2017-04-25 139 views
0

我有一個刷新按鈕和一個SessionManager(會話只是一個開始日期和結束日期)。我希望當我點擊刷新按鈕時,會話被下載並顯示。我沒有問題要這樣做。爲什麼我點擊更多我的qt應用程序很慢?

但是當我點擊了10次之多時,應用程序在10或15秒內沒有回覆。當我點擊一次或兩次時,我沒有任何問題。

我讀取調試輸出,有很多下載相同的文件,而不是一個donwload。

這是我的SessionManager類;它下載一個json文件

class SessionManager : public QObject 
{ 
    Q_OBJECT 
    bool m_has_reply_finished; 

public: 
    explicit SessionManager(); 
    void setAccessToken(const QString& accessToken); 
    void setTimeout(int timeoutMS = 3000); 

    const QString& getDownloadedSessions(); 
    bool isDownloading(); 
    bool isFinished(); 

signals: 
    void onSucceeded(); 
    void onFailed(); 
    void onTimeOut(); 

public slots: 
    void downloadSessions(); 
    void replyfinished(QNetworkReply *reply); 
    void OnTimeOut(); 

private: 
    QString m_downloaded_sessions_string; 
    bool m_is_downloading; 
    QNetworkReply* m_last_network_reply; 
    QMutex m_mutex; 
    QNetworkAccessManager m_manager; 
    QString m_access_token; 
    int m_timeout_ms; 
}; 

SessionManager::SessionManager(): m_has_reply_finished(false), m_is_downloading(false), m_last_network_reply(NULL), m_timeout_ms(3000) 
{ 

} 

void SessionManager::setAccessToken(const QString& accessToken) 
{ 
    m_access_token = accessToken; 
} 

void SessionManager::setTimeout(int timeoutMS) 
{ 
     m_timeout_ms = timeoutMS; 
} 

void SessionManager::downloadSessions() 
{ 
    if (m_is_downloading) 
     return; 


    m_has_reply_finished = false; 
    m_is_downloading = true; 

    QUrl url("http://website.com/api/seance"); 

    QNetworkRequest request; 
    request.setUrl(url); 
    request.setRawHeader("Accept", "application/json"); 
    request.setRawHeader("Authorization", (QString("Bearer ") + m_access_token).toUtf8()); 


    QTimer::singleShot(m_timeout_ms, this, SLOT(OnTimeOut())); // timeout => error 
    QObject::connect(&m_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyfinished(QNetworkReply *))); 

    m_last_network_reply = m_manager.get(request); 
} 

const QString& SessionManager::getDownloadedSessions() 
{ 
    //QMutexLocker locker(&m_mutex); 
    return m_downloaded_sessions_string; 
} 

bool SessionManager::isDownloading() 
{ 
    //QMutexLocker locker(&m_mutex); 
    return m_is_downloading; 
} 

bool SessionManager::isFinished() 
{ 
    //QMutexLocker locker(&m_mutex); 
    return m_has_reply_finished; 
} 

void SessionManager::replyfinished(QNetworkReply *reply) 
{ 
    //QMutexLocker locker(&m_mutex); 

    if (reply == m_last_network_reply) 
    { 
     m_last_network_reply = NULL; 
    } 

    QString str = QObject::tr(reply->readAll()); 
    if (!str.isEmpty()) 
     m_downloaded_sessions_string = str.toUtf8(); 

    m_has_reply_finished = true; 
    m_is_downloading = false; 

    // reply 
    if(reply->error() == QNetworkReply::NoError) 
    { 
     // JSON layer 
     //QJsonDocument d = QJsonDocument::fromJson(str.toUtf8()); 
     //QJsonObject json = d.object(); 

     //m_expires_in_seconds = (int64_t) json["expires_in"].toDouble(); 
     //qDebug("SessionManager QNetworkReply::NoError"); 
     emit onSucceeded(); 
    } 
    else 
    { 
     //m_expires_in_seconds = 0; 
     //qDebug((QString("SessionManager QNetworkReply::Error (") + QString::number((int)reply->error()) + QString(")")).toUtf8()); 
     emit onFailed(); 
    } 

    //qDebug(str.toUtf8()); 
    reply->deleteLater(); 
} 

void SessionManager::OnTimeOut() 
{ 
    //QMutexLocker locker(&m_mutex); 

    if (m_last_network_reply) 
    { 
     m_last_network_reply->abort(); 
     m_last_network_reply->deleteLater(); 
     m_last_network_reply = NULL; 
    } 

    if(!m_has_reply_finished) 
    { 
     emit onTimeOut(); 
    } 

    m_has_reply_finished = true; 
    m_is_downloading = false; 
} 

這是我的MainWindow。在主窗口包含refreshbutton和插槽:

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow), 
    m_sessionlist(NULL) 
{ 
    ui->setupUi(this); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::Construct(AuthenticationManager * authentication_manager, SessionManager *session_manager) 
{ 
    m_authentication_manager = authentication_manager; 
    m_session_manager = session_manager; 

    connect(ui->sessionRefreshPushButton, SIGNAL (released()), this, SLOT(OnRefreshSessionsButtonClicked())); 


    QObject::connect(m_session_manager, SIGNAL(onSucceeded()), this, SLOT(OnDownloadSessionsSucceded())); 
    QObject::connect(m_session_manager, SIGNAL(onFailed()), this, SLOT(OnDownloadSessionsFailed())); 
    QObject::connect(m_session_manager, SIGNAL(onTimeOut()), this, SLOT(OnDownloadSessionsTimeOut())); 

} 

void MainWindow::OnRefreshSessionsButtonClicked() 
{ 
    qDebug("OnRefreshSessionsButtonClicked\n"); 
    if (m_session_manager->isDownloading()) 
    { 
     return; 
    } 

    ui->sessionRefreshPushButton->setEnabled(false); 
    ui->sessionRefreshPushButton->setVisible(false); 

    qDebug("m_session_manager->downloadSessions\n"); 
    m_session_manager->setAccessToken(m_authentication_manager->accessToken()); 
    m_session_manager->setTimeout(5000); 
    QTimer::singleShot(0, m_session_manager, SLOT(downloadSessions())); 
} 

void MainWindow::OnDownloadSessionsSucceded() 
{ 
    qDebug("OnDownloadSessionsSucceded\n"); 
    LoadSessions(); 
    ui->sessionRefreshPushButton->setEnabled(true); 
    ui->sessionRefreshPushButton->setVisible(true); 
} 

void MainWindow::OnDownloadSessionsFailed() 
{ 
    qDebug("OnDownloadSessionsFailed\n"); 
    ui->sessionRefreshPushButton->setEnabled(true); 
    ui->sessionRefreshPushButton->setVisible(true); 
} 

void MainWindow::OnDownloadSessionsTimeOut() 
{ 
    qDebug("OnDownloadSessionsTimeOut\n"); 
    ui->sessionRefreshPushButton->setEnabled(true); 
    ui->sessionRefreshPushButton->setVisible(true); 
} 
+0

在Qt論壇上提出這個問題是個好主意:https://forum.qt.io/ – cppxor2arr

回答

3

每次SessionManager :: downloadSessions()被調用AFAIS,一個新的信號槽連接被建立。所以15日「點擊」,replyfinished()被調用15次。

因此,無論是使用Qt :: UniqueConnection還是僅在構造函數上調用connect()一次。

相關問題