千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:合肥千锋IT培训  >  技术干货  >  QT使用教程之信号与槽

QT使用教程之信号与槽

来源:千锋教育
发布人:qyf
时间: 2023-02-13 17:17:17

  1、信号与槽机制介绍

  理解:观察者模式。

  信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。

图片2

  2、connect函数+系统自带的信号和槽

  connect(sender, signal, receiver, slot);

  参数: 1、信号发出者 2、信号 3、信号的接受者 4、接受到信号执行任务(槽函数)

图片3

  信号:

  void clicked(bool checked = false);

  槽函数:

  void close();

  举例:点击窗口内定义的按钮,关闭窗口

  //创建按钮

  QPushButton *button =new QPushButton("点击关闭窗口",this);

  this->resize(600,400);

  //信号与槽

  connect(button,&QPushButton::clicked,this,&Widget::close);

  3、自定义信号与槽

  步骤1:确定场景

  老师饿了,学生请客

  小哥敲门,家人开门

  步骤2:添加老师类和学生类

  步骤3:在老师类中声明信号+在学生类中声明并实现槽函数

  teacher.h(信号:一般在signals里面写,返回值void,参数可以存在,仅声明不需要实现,可以重载)

  signals: void hungury();

  student.h(槽函数:一般在public slots里面写,对于一些高版本的qt来说,也可以写到public或者全局;返回值void,参数可以存在,需要声明并实现,可以重载)

  public slots: void treat();

  student.cpp

  #include

  void Student::treat(){

  qDebug()<<"请老师吃饭";

  }

  步骤4:创建对象+信号与槽连接

  this->tea = new Teacher(this);

  this->stu = new Student(this);

  connect(tea,&Teacher::hungury,stu,&Student::treat);

  步骤5:触发信号(下课)

  widget.h(声明触发信号的成员函数)

  void ClasOsver();

  widget.cpp(定义触发信号的成员函数+调用该成员函数)

  void Widget::ClasOsver(){

  emit tea->hungury();

  }

  补充:信号连接信号

  点击按钮,请吃饭

  方式一:

  connect(button,&QPushButton::clicked,this,&Widget::ClasOsver);

  方式二:信号连接信号

  connect(button,&QPushButton::clicked,tea,&Teacher::hungury);

  4、重载自定义信号与槽

  步骤1:重新写信号声明(带参数)

  void hungury(QString food);

  步骤2:重新写槽函数声明及定义(带参数)

  void treat(QString food); void Student::treat(QString food){ qDebug()<<"请老师吃饭"<<food; p="" }<="">

  步骤3:由于函数重载了,所以需要利用函数指针指向函数地址,然后在做连接

  void (Teacher::*teachersignal)(QString) = &Teacher::hungury;

  void (Student::*studentslot)(QString) = &Student::treat;

  connect(tea,teachersignal,stu,studentslot);

  补充:Qt4版本信号槽写法(了解)

  connect(tea,SIGNAL(hungury(QString)),stu,SLOT(treat(QString)));

  使用注意:

  1、Qt5在语法上是完全兼容4的,反之不可以。

  2、如果是Qt4版本的信号与槽写法,一定要注意信号和槽的名称不要写错。

  知识点5:信号与槽总结

  自定义信号槽注意事项:

  1、发送者与接受者需要是QObject的子类(槽函数全局,lambda除外)

  2、信号和槽函数返回值都是void

  3、信号需要声明不需要定义实现,槽函数需要声明也需要定义实现()。

  4、槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;

  5、使用 emit 在恰当的位置发送信号;

  6、使用connect()函数连接信号和槽。

  7、任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数。

  8、信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。

  如果信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少)。

  举例:

  signal(QSting)和slot(QSting)√

  signal(QSting,QSting)和slot(QSting)√

  signal(QSting)和slot(QSting,QSting)×

  signal(QSting,QSting,int)和slot(QSting,QSting)√

  signal(QSting,QSting,int)和slot(QSting,int)√

  拓展:

  1、信号与槽对应可以一对一,一对多(发出信号,槽函数一个一个执行,顺序不确定),多对一(任意信号发出,槽函数都会执行)

  2、信号可以连接信号

  3、槽可以被断开链接(disconnect),槽也可以被取消链接(当一个对象delete了,取消这个对象上的槽)

  4、使用c++11中的lambda表达式。

  6、Lambda表达式

  概念:C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。

  语法:

  [capture](parameters) mutable ->return-type{statement}

  1、[capture]捕获列表,捕获的是那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量

  2、(parameters)参数列表,与普通函数的参数列表一致的。

  3、 mutable可修改标示符,按值传递捕获列表时(默认仅读权限),加上mutable修饰符后,可以修改按值传递进来的拷贝

  4、->return-type 返回值类型

  5、{statement}函数体,内容跟普通函数一致。

  注意:

  1、[]标识一个Lambda的开始,这部分必须存在,不能省略。

  空 没有使用任何函数对象参数

  = 函数体内可以使用Lambda所在作用范围内所有可见的局部变量,值传递

  & 函数体内可以使用Lambda所在作用范围内所有可见的局部变量,引用传递

  a 将a按值进行传递

  &a 将a按引用进行传递

  this 函数体内可以使用Lambda所在类中的成员变量

  a, &b 将a按值进行传递,b按引用进行传递。

  =,&a, &b 除a和b按引用进行传递外,其他参数都按值进行传递

  n &, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。

  2、()参数列表,如果不需要传递参数的话,()可以一同省略。

  3、如果使用mutable,参数列表()不能省略的即使参数为空;如果使用mutable,修改拷贝,而不是值本身。

  4、返回值类型,如果不需要,->return-type都可省略。

  5、{函数体},可以使用参数列表,也可以使用捕获列表。

  使用:

  1、通过lambda表达式输入内容

  [](){ qDebug()<<"lambda is running!"; }();

  等同于

  auto fun = [](){ qDebug()<<"lambda is running!"; }; fun();

  2、测试参数列表和可修改标示符(如果无mutable,m=300报错)

  int m=10;

  auto fun = [m](int a,int b)mutable{ qDebug()<<"lambda is running!"; m=300; return a+b; };

  int sum=fun(100,200);

  qDebug()<<sum;< p="">

  3、槽函数一般可用lambda表达式

  QPushButton * myBtn = new QPushButton ("点击",this);

  this->resize(600,400);

  connect(myBtn,&QPushButton::clicked,this,[=] () { qDebug() << "按钮被按下"; } );

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

unity快捷键大全

2023-08-28

unity射线检测多个物体

2023-08-28

unity富文本字体大小

2023-08-28

最新文章NEW

unity性能优化指标

2023-08-28

unity开发常用框架

2023-08-28

unity玻璃材质球

2023-08-28

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>