如何从非qt类向qt类发送信号?

时间:2014-01-25 07:33:35

标签: qt

我创建了一个qt类,只用于制作gui并在gui上显示数据。

我不想冻结gui,这就是为什么我创建另一个non_qt类来执行操作的原因所以我在non_qt类的gui类中创建了一个对象并传入参数并启动它在一个新的线程中。

现在完成操作后,我想通知gui类,以便显示结果。

我也想访问gui类的状态栏,所以当non_qt类执行操作时,它可以在gui上显示一些消息..

(我尝试过qt类,但它没有工作,这就是为什么我创建了non_qt类..使用non_qt类线程部分工作正常但是信号部分没有工作所以我是这样的无法通知gui类)。

所以请帮助我如何从一个非qt类发送信号到qt类????

1 个答案:

答案 0 :(得分:2)

信号是一个概念,仅适用于派生自QObject的类。

如果要触发插槽,则不需要信号。如果接收对象位于同一个线程中(且只有),则可以直接在reciving对象上调用slot方法。

例如,给定一个带有插槽的GUI对象的实例:

MainWindow * mainWindow;

class MainWindow : public QWidget {
  Q_OBJECT
  ...
  Q_SLOT void setStatus(const QString &);
  ...
};

您可以这样做:

// The assert is essential to prevent bad bugs. If it triggers,
// you must use `QMetaObject::invokeMethod` instead.
Q_ASSERT(mainWindow->thread() == QThread::currentThread());
mainWindow->setStatus("Finished");

如果接收对象可能存在于另一个线程中,或者您不想担心线程问题,则必须使用QMetaObject::invokeMethod,如下所示:

// This is always safe. No need for asserts.
QMetaObject::invokeMethod(mainWindow, "setStatus",
                          Q_ARG(QString, "Finished"));

invokeMethod的这个重载将正确地选择连接类型,具体取决于接收对象是否在同一个线程中运行。如果接收者在同一个线程中,则该呼叫是直接呼叫。如果它在另一个线程中运行,则调用将转换为QMetaCallEvent并发布到接收对象。这是线程安全的,不需要接收对象的setStatus方法是线程安全的。