Sent extra data by signal and slot of Qt
-
@
void MainWindow::update_data(QStringList const &data)
{
int const size = data.size();
for(int i = 0; i != size; ++i)
{
QNetworkReply *reply = theme_get_->request_html(data[i]);
connect(reply, SIGNAL(finished()), this, SLOT(update_message_number()));
}
}void MainWindow::update_message_number()
{
auto result = theme_get_->read_html(qobject_cast<QNetworkReply *>(sender()) );
if(!result.first) qDebug() << result.second;int const number = parser_.get_anime_live_message_number(result.second); anime_live_model_->set_current_message_number(/*index of the row*/, number);
}
@As the source codes show, I need to send the index(i) to the update_message_number()
but don't know how to achieve by the signal and slot mechanismI have one solution, declare a map, then
@void MainWindow::update_data(QStringList const &data)
{
int const size = data.size();
for(int i = 0; i != size; ++i)
{
QNetworkReply *reply = theme_get_->request_html(data[i]);
connect(reply, SIGNAL(finished()), this, SLOT(update_message_number()));
mapper.insert(std::make_pair(reply, i) );
}
}void MainWindow::update_message_number()
{
auto result = theme_get_->read_html(qobject_cast<QNetworkReply *>(sender()) );
if(!result.first) qDebug() << result.second;int const number = parser_.get_anime_live_message_number(result.second); if(mapper.find(sender()) != mapper.end() ) anime_live_model_->set_current_message_number(mapper[sender()], number); else QTimer::single_shot(500, this, SLOT(update_message_number(number ) ) );
}
@This solution is pretty complicated, how could I solve it by a better way?
-
Quite expect the new signal and slot mechanism of Qt5
Looks like it is not text-base again and able to co-work
with bind, function and lambda -
Your possibilites:
- use QSignalMapper to map a QNetworkReply to an index (and which is also the object-oriented-correct version of sender())
@
connect(signalMapper,
static_cast<void (QSignalMapper::*)(int)>(&QSignalMapper::mapped),
this,
&MainWindow::update_message_number);
for (int i = 0; i != size; ++i)
{
...
signalMapper->setMapping(reply, i);
connect(reply,
&QNetworkReply::finished,
signalMapper,
static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
}
@- use a lambda to pass the local i
@
for (int i = 0; i != size; i++)
{
...
connect(reply, &QNetworkReply::finished, this, i { update_message_number(i); });
}
@
- use QSignalMapper to map a QNetworkReply to an index (and which is also the object-oriented-correct version of sender())
-
Do Qt4.8.2 support this kind of signal and slot mechanism?
if I could connect the signal and slot by any callable things like std::function
then I could bind the data directly -
I tried it, looks like Qt4.8.2 do not support it yet?
Are you using Qt5.0?I think it is still under developing -
No, the new connection syntax is exclusive to Qt 5. But you can still use the QSignalMapper solution and the ordinary connection syntax.
-
I tried QSignalMapper, but I still need the original sender--reply
QSignalMapper could bind int, but I don't know the original sender