2010-06-16 16 views
11

मैं एक आवेदन जो सर्वर के लिए फ़ाइल की सामग्री अपलोड करता है पर काम कर रहा हूँ के लिए इंतज़ार कर।एक संकेत

सर्वर पर फ़ाइल मैं उपयोग कर रहा हूँ 'QNetworkAccessManager' वर्ग अपलोड करने के लिए। चूंकि यह एसिंक्रोनस तरीके से काम करता है, इसलिए मैंने इसे QEventLoop का उपयोग कर सिंक्रोनस तरीके के रूप में काम करने के लिए बदल दिया।

Class FileTransfer 
{ 
Public : 
    QNetworkAccessManager mNetworkManager; 
    Void Upload(QNetworkRequest request, QIODevice *data) 
    { 
      responce = mNetworkManager.put(request, data); 
      EventLoop.exec(); 
      ReadResponce(responce); 
     } 

     Void Stop() 
     { 
      responce ->close(); 
     } 
} 

मेरी नमूना आवेदन में मैं 2 खिड़कियां है। प्रगति दिखाने के लिए फाइलों का चयन करने के लिए पहला और दूसरा।

जब उपयोगकर्ता पहली विंडो में अपलोड बटन पर क्लिक करता है, तो दूसरी विंडो प्रदर्शित की जाएगी और फिर मैं फ़ाइल ट्रांसफर ऑब्जेक्ट बना सकता हूं और अपलोड करना प्रारंभ कर सकता हूं।

फ़ाइल अपलोड करते समय उपयोगकर्ता खिड़की मैं उस के बाद 'FileTransfer' के बंद फोन मैं 'FileTransfer' वस्तु को नष्ट की नाशक में तो प्रपत्र बंद कर देता है, तो।

लेकिन यहां अपलोड करें() फ़ंक्शन अभी तक पूरा नहीं हुआ है, इसलिए यह क्रैश हो जाएगा।

कृपया मुझे करने में मदद: कैसे अपलोड जब तक 'स्टॉप()' समारोह में प्रतीक्षा करने के लिए() फ़ंक्शन

उत्तर

19

मैं क्या अपने कोड से देख सकते हैं से, आप एक QEventLoop को क्रियान्वित कर रहे हैं, लेकिन आप वास्तव में किसी भी संकेत करने के लिए अपने "छोड़ने" स्लॉट कनेक्ट नहीं कर रहे हैं। उदाहरण के रूप में नीचे ले लो, लॉगिन एक QHttp है - और कोड कुछ अलग से लिया जाता है - लेकिन सिद्धांत लागू होता है। अगर मैं आपकी क्वेरी गलत किया है

/* Create the QEventLoop */ 
QEventLoop pause; 
/* connect the QHttp.requestFinished() Signal to the QEventLoop.quit() Slot */ 
connect(&login, SIGNAL(requestFinished(int, bool)), &pause, SLOT(quit())); 
/* The code that will run during the QEventLoop */ 
login.request(header,&logmein,&result); 
/* Execute the QEventLoop - it will quit when the above finished due to the connect() */ 
pause.exec(); 

यह आपके कोड के लिए लागू किया जा सकता है अगर मैं गलत नहीं हूँ, इस तरह ...

/* connect the signal to the relevant slot */ 
connect(&mNetworkManager, SIGNAL(finished(QNetworkReply)), &EventLoop, SLOT(quit())); 
/* Execute the code that will run during QEventLoop */ 
responce = mNetworkManager.put(request, data); 
/* Execute the QEventLoop */ 
EventLoop.exec(); 

क्षमा याचना! मैं ब्रेक के बाद फिर से क्यूटी के साथ पकड़ने जा रहा हूं, लेकिन मेरा मानना ​​है कि इसका मतलब यही है! सौभाग्य!

+0

हाँ, मैं जैसे ही हम खत्म स्लॉट के रूप में घटना पाश बाहर निकलने के लिए कोड जोड़ा। लेकिन समस्या तब होती है जब फ़ाइल कनेक्शन को बंद कर देती है और ऑब्जेक्ट को हटा देती है। लेकिन अपलोड फ़ंक्शन अभी तक पूरा नहीं हुआ है। इस समय यह दुर्घटनाग्रस्त हो जाएगा। –

0

मुझे लगता है कि आप अपने अपलोड समारोह में ऐसा ही कुछ जोड़ने की जरूरत है पूरा हो गया है:

datacod-qt-tools

आशा है कि यह मदद:

if (upf->openFile()) 
{ 
    reply = manager->post(request, upf); 
    connect(reply, SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(progress(qint64,qint64))); 
    connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); 
    isInProgress = true; 
    emit started(); 
} else 
{ 
    emit finished(true, false, tr("Error: can't open file %1").arg(filename)); 
} 

यहाँ पूरा टेक्स्ट कोड है।

0

व्यक्तिगत रूप से, मैं इन उत्तरों से किसी का उपयोग नहीं करने के लिए सलाह देते हैं। सिग्नल में उलटी गिनती को जोड़ने के लिए पर्याप्त होगा।

तो तुम लिख सकते हैं:

Latch latch(1); 
QObject::connect(reply, SIGNAL(finished()), 
        &latch, SLOT(countDown())); 

latch.wait(); 

इसके लिए आपको एक आवरण की आवश्यकता होगी:

class Latch : public QObject { 
    Q_OBJECT 
public: 
    Latch(uint count); 
    void wait(); 
public slots: 
    void countDown(); 
private: 
    gcl::countdown_latch _latch; 
}; 
+0

मैं गलत हो सकता है, लेकिन मुझे नहीं लगता है कि क्योंकि GCL उलटी गिनती कुंडी एक धागा रोकने के लिए क्या मतलब है काम करेंगे है।पुट() कॉल मुख्य जीयूआई थ्रेड में होता है, तो QNetworkAccessManager वेबपृष्ठ को एक अलग थ्रेड में लाता है, और समाप्त() स्लॉट मुख्य जीयूआई थ्रेड में निष्पादित हो जाता है। इसलिए उदाहरण के साथ इस कोड का उपयोग करने से पूरे ऐप को लॉक कर दिया जाएगा। यह संभव होगा कि समाप्त स्लॉट को एक अलग धागे में ले जाएं, लेकिन इसके लिए बहुत अधिक कोड की आवश्यकता होगी जो यहां नहीं दिखाया गया है। – Ph0t0n

संबंधित मुद्दे