Qt Qt中的信号和插槽
问题描述:
我目前在Qt线程上遇到问题。Qt Qt中的信号和插槽
我必须上传一个QThread中的文件列表,但显然一个上传不起作用和/或我的插槽永远不会被调用。如果我把这些方法从线程中解放出来,那么它就可以完美运行
这里是run()方法:
void UploadThread::run()
{
for (int i = 0; i < Window::_listUpload.size(); i++) {
qDebug() << Window::_listUpload[i].getPath();
this->sendFile(Window::_listUpload[i].getPath());
}
}
这里是SENDFILE()方法:
void UploadThread::sendFile(const QString & path)
{
QFreeDesktopMime mime;
QNetworkAccessManager *manager = new QNetworkAccessManager;
QFileInfo fInfo(path);
QNetworkRequest request(QUrl("http://my-url/"));
QNetworkReply *reply;
QString bound = "---------------------------723690991551375881941828858";
QByteArray data(QString("--"+bound+"\r\n").toAscii());
data += "Content-Disposition: form-data; name=\"action\"\r\n\r\n";
data += "\r\n";
data += QString("--" + bound + "\r\n").toAscii();
data += "Content-Disposition: form-data; name=\"file\"; filename=\""+fInfo.fileName()+"\"\r\n";
data += "Content-Type: "+mime.fromFile(path)+"\r\n\r\n";
QFile file(fInfo.absoluteFilePath());
file.open(QIODevice::ReadOnly);
data += file.readAll();
data += "\r\n";
data += QString("--" + bound + "\r\n").toAscii();
data += QString("--" + bound + "\r\n").toAscii();
data += "Content-Disposition: form-data; name=\"desc\"\r\n\r\n";
data += "Description for my image here :)\r\n";
data += "\r\n";
request.setRawHeader(QString("Accept-Encoding").toAscii(), QString("gzip,deflate").toAscii());
request.setRawHeader(QString("Content-Type").toAscii(),QString("multipart/form-data; boundary=" + bound).toAscii());
request.setRawHeader(QString("Content-Length").toAscii(), QString::number(data.length()).toAscii());
reply = manager->post(request, data);
QObject::connect(reply, SIGNAL(uploadProgress(qint64,qint64)), currentThread(), SLOT(receiveUploadProgress(qint64, qint64)));
QObject::connect(manager, SIGNAL(finished(QNetworkReply*)), currentThread(), SLOT(uploadFinished(QNetworkReply*)));
}
这里是我的槽:
void UploadThread::uploadFinished(QNetworkReply *reply)
{
_isFinished = true;
}
void UploadThread::receiveUploadProgress(qint64 bytesSent, qint64 bytesTotal)
{
qDebug() << bytesSent << " " << bytesTotal;
}
你看我的代码中存在问题? 谢谢。
答
好的,我明白了。
对于每次上传,我需要使用exec()启动QEventLoop,并且在上传结束时,我必须使用exit()来完成QEventLoop。它现在像一个魅力。
答
您好像在您的sendFile()
方法中调用QObject::connect()
。
QObject::connect()
用插槽方法连接信号。信号可以使用类似emit signalName()
的东西来触发。
在你的榜样,你的UploadThread头应该是这样的:
class UploadThread: public QThread {
...
signals:
void uploadProgress(int sent, int total);
void uploadFinished(QNetworkReply *reply);
}
不执行信号,它们会自动被Qt实现。
在SENDFILE(),只是称他们为:
...
emit uploadProgress(sent, total);
...
在你的主线程(= GUI线程),那么你应该有一个具有一类插槽处理信号(当前的uploadFinished()和recieveUploadProgress( ) 方法)。如果你想更新GUI,在GUI线程中执行它们是很重要的。
最后你必须连接它们(连接并不意味着打电话给他们)并开始上传。
UploadThread *uploadThread = new UploadThread();
connect(uploadThread, SIGNAL(uploadProgress(...)), objectInGuiThread, SLOT(actualUploadProgressSlot(...)));
uploadThread.start()
查看Qt's Signal & Slot关于如何使用它们的更多信息。
我不必重新实现uploadProgress()和finished()信号,它们分别由QNetworkReply和QNetworkAccessManager实现。我不必手动发射它们。所以,我的代码应该工作,不是吗? –
嗨,你是对的。我错误地解释了你的代码,Sry ...... – mreithub