connect()似乎用错误的命名空间前缀信号

时间:2012-11-17 13:16:41

标签: c++ qt signals slots

我正在尝试使用信号和插槽将信息从另一个线程传递到GUI线程,因为我无法从任何其他线程修改像素图。我遇到了运行时错误:

Object::connect: No such signal QThread::image_change(std::string) in visualiser.cpp:33

从这一点来看,虽然我可能错了,但看起来信号是在错误的命名空间中搜索的,因为它实际上是在Visualiser::image_change()中定义的。

我的代码如下:

Visualiser.cpp:

    QFutureWatcher<void> watcher;
    connect(watcher.thread(), SIGNAL(image_change(std::string)), QCoreApplication::instance()->thread(), SLOT(update_image(std::string)), Qt::QueuedConnection);
    QFuture<void> update_thread = QtConcurrent::run(this, &Visualiser::update_state);
    watcher.setFuture(update_thread);

   ...

    emit(image_change(imageSrc));

   ...

    void Visualiser::update_image(std::string src)
{
    QImage image;
    image.load(src.c_str());
    ui->visualContainer->setPixmap(QPixmap::fromImage(image));
}

visualiser.h:

    signals:
    void image_change(std::string src);

public slots:
    void update_image(std::string src);

2 个答案:

答案 0 :(得分:2)

不要将线程指针传递给connect - 将指针传递给事件的发送者和接收者(like this)。因为您正在给它QThread指针,Qt正在寻找QThread中那些不存在的信号和插槽。如果你给它Visualizer指针,Qt会在Visualizer中查找那些函数,它们确实存在,并且一切都会有效。

希望有所帮助!

答案 1 :(得分:1)

连接的来源和目标是同一个对象this,因此connect调用应为:

connect(this, SIGNAL(image_change(std::string)), this, SLOT(update_image(std::string)));

由于信号将从Visualizer具有亲缘关系的另一个线程发出(参见QObject::moveToThread()),因此与插槽的连接将自动排队,并且将执行插槽通过正确的线程。

但是对于排队连接工作,Qt必须临时存储参数,直到它可以实际调用插槽,这是通过将其转换为QVariant,将其存储在某处,然后将其重新转换为实际类型来完成的。当接收线程准备好执行插槽时。

因此,您需要使用Q_DECLARE_METATYPEstd::string注册到Qt的元类型系统,或者将信号和插槽参数类型更改为已注册的类型(例如QStringQByteArray })。