我试图使用信号和插槽将信息从另一个线程传递到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);
最佳答案
连接的源和目标是同一对象this
,因此connect
调用应为:
connect(this, SIGNAL(image_change(std::string)), this, SLOT(update_image(std::string)));
由于信号将从与
Visualizer
有关联的另一个线程发出(请参见QObject::moveToThread()),因此与插槽的连接将自动排队,并且插槽将由正确的线程执行。但是为了使排队连接正常工作,Qt必须临时存储参数,直到它可以实际调用插槽为止,这是通过将其转换为
QVariant
并将其存储在某个位置,然后在接收线程为准备执行该插槽。因此,您需要使用
std::string
将Q_DECLARE_METATYPE
注册到Qt的元类型系统,或将信号和插槽参数类型更改为已经注册的信号和插槽参数类型(例如QString
或QByteArray
)。关于c++ - connect()似乎为信号添加了错误的命名空间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13430936/