gpt4 book ai didi

c++ - 如果指针指向一个新对象,信号/槽连接会发生什么

转载 作者:行者123 更新时间:2023-11-30 03:02:57 25 4
gpt4 key购买 nike

我有一个带有以下代码的 uploader :

if(!_canceled) {
_reply = _accessManager.put(request, item);

if(_reply) {
_currentItem = item;

bool status = connect(_reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(reportUploadProgress(qint64, qint64)));
pantheios::log(pantheios::debug, "StorageProvider(): connection uploadProgress(qint64, qint64), status", pantheios::boolean(status));
status = connect(_reply, SIGNAL(finished()), this, SLOT(handleFinishedRequest()));
pantheios::log(pantheios::debug, "StorageProvider(): connection finished(), status", pantheios::boolean(status));

} else {
emit noReply();
pantheios::log(pantheios::error, "StorageProvider(): no reply", item.toUtf8());
}

然后在完成的插槽中我这样做:

QNetworkReply *reply =  qobject_cast<QNetworkReply*>(sender());

if(reply->error() > QNetworkReply::NoError) {
pantheios::log(pantheios::error, "StorageProvider(handleFinishedRequest) ", reply->errorString().toUtf8());

if((reply->error() == QNetworkReply::TemporaryNetworkFailureError) || (reply->error() == QNetworkReply::ContentReSendError)) {
// retry the last request
_reply = accessManager.put(reply->request(), _currentItem);
}

} else {
...
}

此 StorageProvider 将能够处理不同的请求,并且回复将具有不同的连接,具体取决于它在哪个函数中创建。回复是一个成员变量的原因是我可以在我做下一个请求之前删除它。

所以,我的问题是,如果我重新指向回复,是否必须重新连接?插槽/信号连接到指针还是对象?另外,有没有更好的方法删除旧回复?

编辑:将已完成请求的处理程序的代码更改为此;

if(_currentReply->error() > QNetworkReply::NoError) { 
pantheios::log(pantheios::error, "StorageProvider(handleFinishedRequest) ", _currentReply->errorString().toUtf8());

if(((_currentReply->error() == QNetworkReply::TemporaryNetworkFailureError) || (_currentReply->error() == QNetworkReply::ContentReSendError)) && (_currentRetries < 4)) {

QNetworkRequest lastRequest = _currentReply->request();
_currentReply->deleteLater();

_currentReply = _accessManager.put(lastRequest, _currentItem);

if(_currentReply) {

bool status = connect(_currentReply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(reportUploadProgress(qint64, qint64)));
pantheios::log(pantheios::debug, "StorageProvider(retry): connection uploadProgress(qint64, qint64), status", pantheios::boolean(status));
status = connect(_currentReply, SIGNAL(finished()), this, SLOT(handleFinishedRequest()));
pantheios::log(pantheios::debug, "StorageProvider(retry): connection finished(), status", pantheios::boolean(status));

} else {
emit noReply();
pantheios::log(pantheios::error, "StorageProvider(retry): AccessManager no reply");
}
}

}

最佳答案

信号连接到对象,而不是指针变量,所以你每次都必须建立新的连接。

要删除回复,只需在 finished() 槽的开头调用 deleteLater():

QNetworkReply *reply =  qobject_cast<QNetworkReply*>(sender());
reply->deleteLater();

这样它将在槽执行结束时被删除。


您可以通过将每个请求(初始请求加上所有重试)包装在其自己的 QObject 派生类中来避免使用 sender():

class PutRequest : public QObject {
Q_OBJECT
private:
QNetworkAccessManager *_manager;
QNetworkReply *_reply;
QIODevice *_item; // Or whatever type the second parameter of put is
public:
explicit PutRequest(QNetworkAccessManager *manager, QNetworkRequest *request, QIODevice *item, QObject *parent = 0)
: QObject(parent), _manager, _reply(0), _item(item)
{
_reply = _manager.put(request, item);
connectSignalsAndSlots();
}

private:
void connectSignalsAndSlots() {
// to delete the reply if the PutRequest object is destroyed
reply_->setParent(this);
// since the reply is encapsulated, the object has to emit its own
// upload progress signal
connect(_reply, SIGNAL(uploadProgress(qint64, qint64)), this, SIGNAL(uploadProgress(qint64, qint64)));
connect(_reply, SIGNAL(finished()), this, SLOT(handleFinishedRequest()));
}

private slots:
void handleFinishedRequest() {
_reply->deleteLater();
if(reply->error() != QNetworkReply::NoError) {
pantheios::log(pantheios::error, "StorageProvider(handleFinishedRequest) ", reply->errorString().toUtf8());

if((_reply->error() == QNetworkReply::TemporaryNetworkFailureError) || (reply->error() == QNetworkReply::ContentReSendError)) {
// retry the last request
_reply = _manager.put(_reply->request(), _item);
connectSignalsAndSlots();
}

} else {
...
emit finished(this);
}
}
signals:
void uploadProgress(qint64, qint64);
// emitted when the upload is successful (after the possible retries)
void finished(PutRequest*);
};

你会像这样创建请求:

if(!_canceled) {
PutRequest *putRequest = new PutRequest(_accessManager, request, item);

// and you connect putRequest object signals to whatever you connected _reply to

关于c++ - 如果指针指向一个新对象,信号/槽连接会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9780255/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com