【发布时间】:2013-11-13 21:17:39
【问题描述】:
我遇到了以下问题:
我有一个 GUI 元素类和一个 Thread 类。我想在他们之间交换信号。然而,它只在一个方向上起作用。我可以成功地从主 GUI 窗口向线程发送信号。但是,当我想从线程向调用线程的进程发送信号时,它不起作用。这是我的做法:
bool GfxMapItem::mapSwitch(int seqidx)
{
...
importMapThread_ = new ImportMapThread(sequence_->item(seqidx));
connect(GUI_UI->analExportButton, SIGNAL(clicked()), importMapThread_, SLOT(interrupt1()), Qt::QueuedConnection); //<-- this one works perfectly
connect(importMapThread_, SIGNAL(progress(int)), this, SLOT(loadMap(int)), , Qt::QueuedConnection); // <-- this one unfortunatelly doesn't
...
}
线程代码非常简单,它只发出信号(我已经检查了当我将线程与自身连接时它是否有效)。
void ImportMapThread::run()
{
QLOGX("Running ImportMapThread...");
QLOGINC;
emit this->progress(100);
QLOGX("Stopping ImportMapThread...");
}
线程标题如下所示:
class ImportMapThread : public InterruptibleThread
{
Q_OBJECT
private:
...
protected:
...
public:
ImportMapThread(SeqItem *p);
signals:
void progress(int value);
void progressReset(int value);
public slots:
virtual void interrupt1();
void loadMap();
protected:
virtual void run();
};
调用该线程的类如下所示:
class GfxMapItem : public QObject, public QGraphicsPixmapItem
{
Q_OBJECT
...
signals:
void mouseOutside();
void mouseMove(const QPointF &pos);
private slots:
void loadMap(int);
protected:
...
};
有什么想法吗?拜托,我的想法已经用完了。
【问题讨论】:
-
什么是
InterruptibleThread,你应该继承自QThread -
InterruptibleThread继承自QThread。 -
我看到 ImportMapThread 包含自定义槽。请注意,这些插槽将在 CALLING 线程中运行,而不是在新线程中运行。来自QThread docs:“重要的是要记住,QThread 实例存在于实例化它的旧线程中,而不是在调用 run() 的新线程中。这意味着 QThread 的所有排队槽都将在旧线程。因此,希望在新线程中调用槽的开发人员必须使用工作对象方法;不应将新槽直接实现到子类 QThread 中。"
-
我无法从您的代码 sn-ps 中看到问题的确切原因,但由于您的代码在错误的线程中运行,因此可能是某些东西被损坏了。如果你想在线程之间进行 2-way 通信,你需要使用一个 Worker QObject(参见QThread documentation 的例子)
-
实际上线程中的这个自定义槽是有效的,问题出在信号上(不是在线程本身,而是在运行线程的进程中)或更可能是槽
loadMap应该是由来自线程的信号调用。 代码在错误的线程中运行是什么意思?
标签: c++ multithreading qt user-interface signals-slots