请选择 进入手机版 | 继续访问电脑版
快捷导航
2 94

Qt学习篇(一):Qt信号槽机制

Serial 于 2018-4-17 20:13 发表在 [技术分享] [复制链接]
       Qt信号槽主要用来解决多窗口之间数据传值的问题,这里我们先来聊聊信号和槽函数;
       信号槽分为信号和槽函数:
  • 信号:是一个函数,这个函数不需要实现,只声明便可以,使用signals关键字限定;
                 函数返回值:void;

                 函数可重载,主要是便于针对不同传递界面单次传递数据数量不同;
                 单个信号可连接多个槽,用于将一方的数据传递到多个界面;
                 多个信号可连接一个槽,用于一方接收多个界面的数据以整合;
  • 槽函数:槽函数为类中的成员函数,自己定义与声明;
                 函数返回值:void;

                 函数可重载(这里未避免对C++不熟悉,解释下重载的感念,重载就是两个或多个函数函数名相同,入参个数各不相同);
                 参数需要与信号的参数一一对应,槽函数的参数个数只可小于或等于信号的参数个数,不可大于;

       下面正式进入信号槽的伪代码实现:
       我们以两个界面之间数据传递为例,同时定义一个Qt Widget项目,对应的存在两个成组存在的.cpp、.h文件(自己命名吧,这里我们以MainWindow,form为两个界面命名);
       我们要实现一个简单的demo,在form中的Edit上输入文本,点击按钮会在MainWindow界面上显示输入的文本。
       那么按照信号槽的原理,我们需要在form.h中声明信号,并写一个信号发送时间的一个函数(发送触发函数):
  1. public slots:
  2.     void pressBtn();

  3. signals:
  4.     void sendData(QString data);
复制代码
这里slots表示槽,signals表示信号。
       因为信号只需声明,那么在form.cpp中只需要实现pressBtn槽函数:
  1. void Form::pressBtn()
  2. {
  3.     emit sendData(ui->lineEdit->text());
  4. }
复制代码
这里emit表示将信号发送,由此知道pressBtn每执行一次将会发送一次信号;对于何时执行pressBtn函数,那边是使用我们之前表明的按钮了,使用connect将按钮与pressBtn函数绑定在一起,其实在我们点击按钮时便实现了一次信号的发送与接收,只不过这是Qt内部集成在按钮事件上了而已,不需要我们来做具体的实现,在我们点击按钮时发送了一个按钮点击的信号,而程序自身接收之后便会执行按钮绑定的执行函数。
       接下来便是实现信号的接收了,首先在MainWindow.h中声明:
  1. private:
  2.     Form* Fm;

  3. public slots:
  4.     void receivData(QString data);
复制代码
receiveData便是接收槽。
       信号槽最主要的便是接下来的信号与槽之间的绑定,方式类似按钮与执行函数之间的绑定:
  1. Fm = new Form();
  2.     connect(Fm,SIGNAL(sendData(QString)),this,SLOT(receivData(QString)));
复制代码
而receiveData接受槽函数便是按照自己的功能来实现便可:
  1. void MainWindow::receivData(QString data)
  2. {
  3.     ui->label->setText(data);
  4. }
复制代码
这样我们便实现了最初预期的效果。

附上我的完整的项目代码吧(这里我就用图片来展示吧)。





ok,信号槽机制到此结束,下次Get到新知识再来。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Connecting & Messaging from Any.

共 2 个关于本帖的回复 最后回复于 2018-5-31 16:07

Serial 中级会员 发表于 2018-5-31 16:07:08 | 显示全部楼层
在进一步测试后发现之前使用QObject后,connect函数使用无错,但是我没有考虑到另一件事,因为我这是线程运行函数,是不依赖于其他任何类的,但是connect的槽函数确是依赖于主线程的,那么将查找不到槽函数;
就算是我new一个主线程对象亦是无用,出现查找不到QObject::(主线程对象)->(槽函数),考虑之后想到主线程是继承于其他类的,往深处探查,最后还是查到QObject身上,那么就好办了,我new一个主线程对象,使用  (主线程对象)->connect();
此时因为connect依赖于主线程,那么我便可以在connect中使用主线程的函数了,同时主线程可以说是继承QObject,connect使用也正常了。
Connecting & Messaging from Any.
举报 使用道具
Serial 中级会员 发表于 2018-5-31 15:13:14 | 显示全部楼层
补充:信号槽链接函数connect属于QObject基类的成员函数,在开启线程类的情况下我们会在run函数中使用C定义的函数,不依赖于任何类,那么此种情况下我们是无法正常使用connect函数的,会报error:“connect”: 找不到标识符;
那么此时我们会想到既然connect是QObject的成员函数,在调用connect时加上QObject便可,尝试new一个对象QObject* object = new QObject;
然后使用object->connect()便可。
Connecting & Messaging from Any.
举报 使用道具
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

推荐板块

精彩推荐

热门排行

明星用户

手机版|小黑屋|AnyMSG ( ©AnyMSG 2009 - 2017 · ICP备16009991号 )

GMT+8, 2019-4-19 12:20