Qt信号和槽机制&emit的使用

1.相关概念:

[1].信号(Signal就是在特定情况下被发射的事件

[2].槽(Slot)就是对信号响应的函数。槽就是一个函数

[3].信号与槽之间的关联:是用 QObject::connect() 函数实现的,其基本格式是:

QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

//信号发出者,处理的信号, 信号接收者,处理动作方法(槽函数)。

注解:

[1].sender 是发射信号的对象的名称,
[2].signal() 是信号名称。信号可以看做是特殊的函数,需要带括号,有参数时还需要指明参数。

[3].receiver 是接收信号的对象名称,slot() 是槽函数的名称,需要带括号,有参数时还需要指明参数。

[4].SIGNAL SLOT Qt 的宏,用于指明信号和槽,并将它们的参数转换为相应的字符串。

使用时需注意:

[1].一个信号可以连接多个槽, 当一个信号与多个槽函数关联时,槽函数按照建立连接时的顺序依次执行,例如:

connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(addFun(int));

connect(spinNum, SIGNAL(valueChanged(int)), this, SLOT(updateStatus(int));

[2]. 多个信号可以连接同一个槽,

connect(ui->rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
connect(ui->rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
connect(ui->rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()))

[3]. 一个信号可以连接另外一个信号

[4]. 严格的情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。如果不匹配,会出现编译错误或运行错误。

[5]. 在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT

[6]. 当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。

2.自定义槽

可当作槽函数的:任意的成员函数,普通全局函数,静态函数。

槽函数需要和信号一致(参数列表,返回值)如果信号没有返回值,槽函数一定没有返回值。

【举例】:让按钮2点击一下,就能改变按钮上的文本。

[1].首先,在.h文件中声明:

[2]在.cpp文件对该函数进行定义:

[3]给按钮联结自定义的槽函数 mySlot:

connect(b2, &QPushButton::released, this, &MainWidget::mySlot);

[4].运行

3.自定义信号

1.信号必须有signals关键字来声明

2.信号没有返回值,但可以有参数。

3.信号就是函数的声明,只需声明,无需定义。

4.emit发射信号

emit是Qt关键字,像其他关Qt扩展一样,它也会被C++预处理器转换成标准的C++代码。

使用:在A中对B使用信号

主要步骤:信号的创建,槽函数的创建,A类信号和B类槽函数的联接和使用

***A类的cpp***
void A::Dome()
{
	B = new B;
	******//在这里要先将B类实例化***
	***//信号与槽需要实例化对象******
	
	connect(this, SIGNAL(mySignal()), B, SLOT( BmySlot1()));
	***//将A类的信号和B类的槽函数链接起来***
	
	emit void AmySignal();
	***//发出信号***
}
***B类的cpp***
void B::BmySlot1()
{
	printf("hello world\n");
	***//实现***
}

【举例】

需求:有两个窗口:主窗口和子窗口,让主窗口的按钮能跳转到子窗口,子窗口的按钮能跳转到主窗口。

疑问点:从主窗口跳转到子窗口,因为主窗口中有子窗口对象。但是要在子窗口中显示主窗口,由于子窗口中没有主窗口的对象。也不能有,否则进入死循环,逻辑错误。

[1].在main函数中把主窗口MainWidget加入进程

int main(int argc, char *argv[])
{
    QApplication a(argc, argv); //创建一个QApplication类对象,有且只有一个应用程序对象!
    MainWidget w1;
    w1.show();
    return a.exec();
 }

[2].创建主窗口,在主窗口中创建一个按钮,并connect到槽函数

setWindowTitle("老大"); //给窗口命名。
    but3.setParent(this);
    but3.setText("切换到子窗口");
    but3.move(50,50);
connect(&but3, &QPushButton::released,this,&MainWidget::changeWin);
//在主窗口类中定义和声明槽函数MainWidget::changeWin
public: void changeWin();
void MainWidget::changeWin(){
    //子窗口显示
    w.show();
    //本窗口隐藏
    this->hide();
}

[3].创建子窗口,并让子窗口加入到主窗口。

创建子窗口文件widget.h/widget.cpp

在主窗口文件中声明子窗口

private: Widget w;

[4]在主窗口中处理子窗口信号

// 先给子窗口添加自定义信号:mySignal,并connect到主窗口的dealSub槽函数

connect(&w, &Widget::mySignal,this,&MainWidget::dealSub);

// mySignal():在子窗口中有申明信号函数:但是没有定义

signals:void mySignal(); //在子窗口中申明信号函数

// dealSub():在主窗口中申明和定义槽函数

public :void dealSub();//申明:

//在相关.cpp文件中定义

void MainWidget::dealSub(){
   w.hide();//子窗口隐藏
   show();  //本窗口显示
}

[5].在子窗口中添加按钮,并让其实现跳转到主窗口

1).在子窗口文件中添加按钮

b3.setParent(this); //通过setParent指定父级
b3.setText("返回上一级窗口");
b3.resize(200, 40);//设置按钮的大小
b3.move(200, 200);//以Qwidget左上角为(0, 0),移动按钮

2).给按钮信号connect子窗口的sendSlot槽函数。

connect(&b3, &QPushButton::clicked,this,&Widget::sendSlot);

3).在子窗口类中声明和定义槽函数

public:void sendSlot();

4).定义槽函数:

void Widget::sendSlot(){
emit mySignal(); //触发子窗口的mySignal()信号。
}
mySinal()函数子窗口中有申明,但没有一个具体实现,这是为何?

答案请看《自定义信号的定义规则第3条》

 

  • 20
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值