当signal and slot需要传送额外参数的时候该怎么办呢?

stereoMatching 2012-08-25 12:08:20

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

我需要多传一笔参数(int),可是Qt signal and slot是base on text的,不可能直接把参数绑进去
我试过QSignalMapper,可是他无法得到另外一笔参数--reply
我尝试把资料存在map中,可是此解法相当丑陋


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 ) ) ); //如果map没有更新,会重复呼叫
}


请问有没有其他办法可以解决这个问题?

真希望Qt5快点出来,Qt5的signal and slot机制改了不少
...全文
243 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
stereoMatching 2012-08-26
  • 打赏
  • 举报
回复

for(int i = 0; i != size; ++i)
{
QNetworkReply *reply = theme_get_->request_html(data[i]);
mapper.insert(std::make_pair(reply, i) );
connect(reply, SIGNAL(finished()), this, SLOT(update_message_number()));

}

mapper的更新顺序要改一下
stereoMatching 2012-08-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

因为finished() 是Qt 框架自己的信号,你是不可以修改的。而且,slot的参数个数是不可以 多于 相应的signal的。
这里有一个解决的办法就是 用连接 finished() 信号,到另一个 中转的slot中,添加了参数在 相应的 连接你需要的slot。
[/Quote]

[Quote=引用 2 楼 的回复:]
自定义一个信号就行了
[/Quote]

请问该如何实做?继承QNetworkReply,加入一个新的信号
并添加data member保存该信号?
这一来可以免去加锁的麻烦,值得一试

大概是这样吧?还没测,不知道是否可行

class newNetWorkReply : public QtNetworkReply
{
public :
newNetWorkReply() : QtNetworkReply(),index_(0)
{
connect(this, SIGNAL(finished()), this, SLOT(call_signal()));
}
void set_index(int index) { index_ = index; }
signals :
void finished(int);

private slots :
void call_signal() { emit finished(int); }

private :
int index_;
};


理想情况我是希望可以直接把参数绑进去,就像std::bind那样
可是Qt4.x的版本不能这样做

另外,原本的那段程式我稍微修改了
QtNetworkReply会把connect的结果queue起来,我不必担心thread safe map没有update


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

//slot
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(mapper[sender()], number);


简单多了,但还是不比直接把参数绑进去来得好
我是学友 2012-08-25
  • 打赏
  • 举报
回复
自定义一个信号就行了
jdwx 2012-08-25
  • 打赏
  • 举报
回复
楼上两位把办法都说了,选一个吧。
dext 2012-08-25
  • 打赏
  • 举报
回复
因为finished() 是Qt 框架自己的信号,你是不可以修改的。而且,slot的参数个数是不可以 多于 相应的signal的。
这里有一个解决的办法就是 用连接 finished() 信号,到另一个 中转的slot中,添加了参数在 相应的 连接你需要的slot。
或者是,你可以自己创建你的finished(int) signal。

16,817

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧