0

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

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

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

我的代码如下:

可视化器.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));
}

可视化器.h:

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

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

2 回答 2

2

不要将线程指针connect传递给 - 将指针传递给事件的发送者和接收者(像这样)。因为您正在给它QThread指针,所以 Qt 正在寻找那些QThread不存在的信号和插槽。如果你给它Visualizer指针,Qt 会在 中寻找那些函数Visualizer,它们真正在哪里,一切都会正常工作。

希望有帮助!

于 2012-11-17T13:23:31.243 回答
1

连接的源和目标是同一个对象,this所以connect调用应该是:

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

由于信号将从另一个线程发出,而不是与其Visualizer有关联的线程(参见QObject::moveToThread()),与槽的连接将自动排队,并且槽将由正确的线程执行。

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

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

于 2012-11-17T19:02:44.373 回答