【问题标题】:SIGNALS and SLOTS in QT5QT5 中的信号和插槽
【发布时间】: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


【解决方案1】:

解决了!事实证明,只有 GUI 元素可以与线程通信。线程可以从其他类型的线程继承,信号和槽都没有问题。问题在于对象 GfxMapItem。由于某种原因,它无法处理正常的通信。

【讨论】:

    【解决方案2】:

    我相信,您应该在运行实现中调用 exec。 Exec 启动事件循环,应该允许发送信号。

    看看:

    int QThread::exec() [protected] 进入事件循环并等待直到 调用 exit(),返回传递给 exit() 的值。这 如果通过 quit() 调用 exit(),则返回值为 0。有必要 调用此函数开始事件处理。

    我希望这会有所帮助。

    【讨论】:

    • 你需要一个事件循环来接收信号,但你不需要一个来发送信号。
    猜你喜欢
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2017-08-01
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    相关资源
    最近更新 更多