Qt中的中信号槽与异步调用

原创 2016年05月31日 14:37:09

Qt中使用信号-槽机制处理跨对象之间的调用,该机制的好处有:
1. 使得调用关系的绑定和解除十分灵活,不必修改类成员函数代码
2. 在不暴露更多全局变量的情况下实现跨命名空间调用
3. 可以多个信号对应多个槽,也可以信号之间绑定,对应于GUI中的逻辑很方便
4. 利用Qt::QueuedConnection可以实现异步调用

一般使用

connect(this, SIGNAL(TestSignal()), this, SLOT(TestSlot()), Qt::AutoConnection)

第四个参数一般省略


以下详细谈谈第4点:

对于一个多线程GUI程序来说,经常遇到的需求是后台有比较复杂的IO、网络、数据处理逻辑,响应的业务逻辑有多个状态,并常伴有延时。这种情况下用多线程处理比用定时器方便。而一旦使用多线程,就涉及到与GUI主线程的同步问题。
从开发者的角度,希望使用的是“线程透明”的交互机制,即直接跨线程修改GUI控件属性;GUI中用户的输入事件传递到数据处理线程中,并在适当时被响应和处理。
我们希望图形库提供以上封装好的方法,不需要开发者手动处理互斥锁、消息队列等。
Qt做到了

在Qt中使用

connect(obj1, SIGNAL(TestSignal()), obj2, SLOT(TestSlot()), Qt::QueuedConnection);

跨越对象异步调用信号-槽。注意在obj2中必须调用消息循环

void processEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents)

这是因为,Qt异步信号槽机制内部基于Event,必须由QObject内置的事件响应函数处理到来的事件,并实际执行槽函数。


Qt中的主要使用以下函数发送消息:

//添加消息到队列末尾
void ​postEvent(QObject * receiver, QEvent * event, int priority = Qt::NormalEventPriority)

//添加消息到队列开头
bool QCoreApplication::​sendEvent(QObject * receiver, QEvent * event)

可以用来发送Qt预定义事件,比如模拟鼠标点击。也可以自定义事件,自定义事件对应ID要大于1024。

一般而言,我们自定义事件的目的本质上是为了远程调用,故直接使用异步信号槽机制即可。除非需要对于传递的数据进行复杂的存储管理,此时再考虑继承Event包含对应数据结构。


以下代码表明,不调用消息循环就无法处理异步信号槽

//test.h
class AsynchronizedSlotTest : public QObject
{
    Q_OBJECT
public:
    AsynchronizedSlotTest();
    void runTest();

    public slots :
        void TestSlot();
signals:
    void TestSignal();
};
//test.cpp

AsynchronizedSlotTest::AsynchronizedSlotTest() : QObject()
{
    //connect(this, SIGNAL(TestSignal()), this, SLOT(TestSlot()), Qt::AutoConnection);
    connect(this, SIGNAL(TestSignal()), this, SLOT(TestSlot()), Qt::QueuedConnection);

}
void AsynchronizedSlotTest::runTest()
{
    emit TestSignal();
}

int main()
{
    AsynchronizedSlotTest slotTest;
    slotTest.runTest();
    return 0;
}

将第6行改成第5行就可以,因为此时Qt::DirectConnection直接调用不依赖消息循环

Qt中的信号和槽之connect----多线程调用全解析(同步/异步)

学Qt也有一段时间了,,,可是对它的connection 函数却不是很了解,也没有考虑一些问题...       比如,信号调用槽问题,是同步的,还是异步的:       connect是4个...
  • etwdone
  • etwdone
  • 2013年05月04日 19:29
  • 4624

Qt 信号-槽的同步与异步处理

通常使用的connect,实际上最后一个参数使用的是Qt::AutoConnection类型:Qt支持6种连接方式,其中3中最主要: 1.Qt::DirectConnection(直连方式)(信号与槽...
  • u011014707
  • u011014707
  • 2014年07月22日 14:33
  • 7515

Qt的signal和slot是同步的,还是异步的?

我们知道Qt以他的signal和slot机制独步天下。但大家在用的时候有没有注意过,signal和slot是异步的,还是同步的呢?为此我问过不少Qt的使用者,有人说是同步的,有人说是异步的,也有人说着...
  • SuperFPE
  • SuperFPE
  • 2011年07月22日 12:26
  • 4710

Qt信号槽分析总结

注:此文是站在Qt5的角度说的,对于Qt4部分是不适用的。 1.先说Qt信号槽的几种连接方式和执行方式。 1)Qt信号槽给出了五种连接方式: Qt::AutoConnec...
  • Andy_93
  • Andy_93
  • 2016年09月28日 10:30
  • 1472

Qt 线程同步与异步处理

1.互斥量(QMutex)         头文件声明:    #include         互斥量声明:    QMutex m_Mutex;         互斥量加锁:    m_Mute...
  • u011014707
  • u011014707
  • 2014年07月23日 09:56
  • 2245

qt延时 QT中简单的延时办法

来自 http://www.qtgtk.com/qt延时-qt中简单的延时办法/ QEventLoop eventloop; QTimer::singleShot(time, &eve...
  • xi__q
  • xi__q
  • 2014年07月08日 11:04
  • 10891

Qt中定时器使用的两种方法

Qt中定时器的使用有两种方法,一种是使用QObject类提供的定时器,还有一种就是使用QTimer类。          其精确度一般依赖于操作系统和硬件,但一般支持20ms。下面将分别介绍两种方法来...
  • Andy_93
  • Andy_93
  • 2016年10月10日 14:30
  • 14367

QT信号和槽用于对象之间的通信

信号和槽 信号和槽用于对象间的通讯。信号/槽机制是Qt的一个中心特征并且也许是Qt与 其它工具包的最不相同的部分。 在图形用户界面编程中,我们经常希望一个窗口部件的一个变化被通知给另一个 窗口部件...
  • zhang2531
  • zhang2531
  • 2016年03月05日 10:41
  • 2831

Qt源码分析-事件如何触发信号

/*信号触发点 在分析Qt的事件循环时,在Windows平台的事件分发器处理函数 QEventDispatcherWin32::processEvents中最终只有DispatchMessage(...
  • l451800869
  • l451800869
  • 2014年01月07日 17:23
  • 1531

Qt信号和槽的连接--发射信号而槽未响应

connect函数应该在哪里连接信号和槽呢?应该怎么用呢?为什么会出现槽不响应信号的问题呢?...
  • qq_33221028
  • qq_33221028
  • 2017年05月15日 18:39
  • 1855
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Qt中的中信号槽与异步调用
举报原因:
原因补充:

(最多只允许输入30个字)