QT学习01------信号与槽

大耗子 2020年06月27日 210次浏览

文章链接:https://codemouse.online/archives/2020-06-27-23-10-46

乱码问题与QString转化为char*

  • 乱码就在需要输出中问的文件上加上这个宏
    #pragma execution_character_set("utf-8")

  • QString 转成 char *
    .ToUtf8() 转为 QByteArray
    .Data() 转为 char *

按钮控件常用API

  • 创建 QPushButton * btn = new QPushButton("文字",父亲);或参数为空
  • 设置父亲 setParent(this)
  • 设置文本 setText("文字")
  • 设置位置 move(宽,高)
  • 重新指定窗口大小 resize(宽,高)
  • 设置窗口标题 setWindowTitle("文字")
  • 设置窗口固定大小 setFixedSize(宽,高)

对象树

  • 当创建的对象在堆区时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作,将对象会放入到对象树中。
  • 一定程度上简化了内存回收机制

信号和槽

  • 连接函数 :connect
    参数:
    参数1 信号的发送者
    参数2 发送的信号(函数地址)
    参数3 信号的接受者
    参数4 处理的槽函数 (函数的地址)
    **使用范例:**connect(btn , &QPushButton::click , this , &QWidget::close );
  • 注意:在QT5版本中,信号和槽函数参数不对应会报错,QT4不会。

自定义信号

  • 写到 signals下
  • 返回值是 void
  • 需要声明,不需要实现
  • 可以有参数
  • 可以重载

自定义槽函数

  • 返回void
  • 需要声明 ,也需要实现
  • 可以有参数 ,可以重载
  • 写到slot下 或者public 或者全局函数

触发自定义的信号

emit 自定义信号函数
例如: emit teacher->hungry("宫保鸡丁");

当自定义信号和槽出现重载

  • 需要利用函数指针 明确指向函数的地址
    例如:
void(Teacher:: *teacherSignal)(QString  ) = &Teacher::hungry;
void(Student:: *studentSlot)(QString  )  = &Student::treat;
connect(zt,teacherSignal,st,studentSlot);
  • 信号可以连接信号
  • 断开信号 disconnect,参数与connect一样

知识点总结

  • 信号可以连接信号
  • 一个信号可以连接多个槽函数
  • 多个信号可以连接同一个槽函数
  • 信号和槽函数的参数 必须类型一一对应
  • 信号和槽的参数个数是不是要一致?
    信号的参数个数 可以多于槽函数的参数个数,但绝不可以少,且参数要对应上
  • 信号槽可以断开连接 disconnect

Qt4版本connect的写法

  • connect( 信号的发送者, 发送的信号SIGNAL( 信号) ,信号接受者, 槽函数SLOT(槽函数) )
    例子: connect(zt,SIGNAL(hungry(QSring)) , st , SLOT(treat(QSring)));
  • 优点 参数直观
  • 缺点 编译器不会检测参数类型(信号和槽函数参数不对应不会报错)

Lambda表达式

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

[capture](parameters) mutable ->return-type
{
	statement
}
[函数对象参数](操作符重载函数参数)mutable ->返回值{函数体}
  • 在使用Lanbda表达式的时候,connect可以省略第三个参数。
connect(btn2,&QPushButton::clicked, [=](){});

函数对象参数

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

函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。

函数对象参数有以下形式:

  • 空。没有使用任何函数对象参数。
  • =。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
  • &。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。
  • this。函数体内可以使用Lambda所在类中的成员变量。
  • a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。
  • &a。将a按引用进行传递。
  • a, &b。将a按值进行传递,b按引用进行传递。
  • =,&a, &b。除a和b按引用进行传递外,其他参数都按值进行传递。
  • &, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。

操作符重载函数参数

标识重载的()操作符的参数,没有参数时,这部分可以省略。
参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。

可修改标识符

  • mutable声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。
    范例参考:
QPushButton * myBtn = new QPushButton (this);
QPushButton * myBtn2 = new QPushButton (this);
myBtn2->move(100,100);
int m = 10;
connect(myBtn,&QPushButton::clicked,this,[m] ()mutable { m = 100 + 10; qDebug() << m; });
connect(myBtn2,&QPushButton::clicked,this,[=] ()  { qDebug() << m; });
qDebug() << m;

函数返回值

  • ->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。

函数体

  • {},标识函数的实现,这部分不能省略,但函数体可以为空。

参考范例代码

下载请点击
https://store.codemouse.online/pic/0d9636abaa91bf4850b2fd54b902faff.rar

总体总结框架图

Qt信号和槽