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 mechanism

    I 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); });
      }
      @


  • 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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.