QT信号与槽函数

1.信号与槽函数的作用(通信机制)
        用来在组件和组件,组件和窗口之间通信
        温故知新: Linux中进程间通信signal(你要捕捉的信号,函数指针) 
                                                                      QT信号         槽函数
        信号:QT中给每个组件都定义了信号,每个信号都有它特定的触发条件(QT助手有介绍每个信号在什么条件下触发)
              QT中所有的信号,本质上都是个函数,但是有点特殊,信号只有声明,没有源代码
              比如:以按钮为例,常用的信号如下
                     [signal] void QAbstractButton::clicked(bool checked = false)  //当按钮按下去,然后松开的时候自动触发这个信号
        如何查看某个组件有哪些信号呢?
              方法一:在QT助手中查看(前面有[signal]全部都是信号)
              方法二:在QT creator开发环境中右键点击组件,选择转到槽,会自动弹出对话框,对话框中有所有的信号
        槽函数:当某个信号触发的时候,跟这个信号对应的槽函数会被自动调用执行

  2.如何关联信号与槽函数
        第一种方法:借助集成开发环境,右键转到槽函数
             头文件中会自动生成槽函数的声明
                      private slots:   //声明了一个私有的槽函数
                          void on_pushButton_clicked();  //槽函数的原型声明
             自动生成的槽函数,命名有规律
                      on_对象的名字_信号的名字();
             注意:组件对象的名字是可以修改的(类对象视图中双击组件对象的名字,即可修改)
        第二种方法:程序员调用connect函数手动关联信号与槽函数
             connect(QObject *sender, PointerToMemberFunction signal,QObject *receiver, PointerToMemberFunction method)
                  参数:sender --》信号的发送者,指针
                            signal --》发送什么信号
                            receiver --》信号的接收者
                            method --》需要调用的槽函数
                                    槽函数命名时候,可以跟自动生成的槽函数命名规律保持一致,也可以自行单独命名
           比如:connect(ui->handlebt,SIGNAL(clicked(bool)),this,SLOT(fun())); //关联了handlebt这个按钮的clicked信号和槽函数fun()
           QT使用技巧:头文件中声明了函数,右键选择refactor,可以在.cpp生成函数的定义       

 

//右键转到槽,自动生成了槽函数的声明和定义,代码空着,留给程序员自由发挥
void MainWindow::on_mybt_clicked()
{
    qDebug()<<"按钮被彭老师按下去,松开了";
}

void MainWindow::on_mybt_released()
{
    qDebug()<<"按钮松开了";
}

void MainWindow::on_testbt_clicked()
{
    qDebug()<<"另外一个按钮被点击了";
}

 

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //我手动关联ui中的按钮和槽函数
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(fun()));

    //在主窗口类的构造函数中,新建一个按钮对象
    QPushButton *mybt=new QPushButton("实现ui做法二:手动写代码创建了该按钮对象",this);
    //设置坐标,宽高
    mybt->setGeometry(200,300,300,70);
    connect(mybt,SIGNAL(clicked()),this,SLOT(on_mybt_clicked()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::fun()
{
    qDebug()<<"我自己写的槽函数fun调用了";
}

void MainWindow::on_mybt_clicked()
{
    qDebug()<<"我自己写的槽函数on_mybt_clicked调用了";
}

 补充知识点:

QObject --》QT中所有类的祖先

4.总结信号与槽的特点
         第一个:一个类如果要使用信号以及槽函数,那么该类的定义中必须加上Q_OBJECT宏定义
                  Q_OBJECT:QT把它称为元对象系统,作用支持信号与槽这种机制
         第二个:同一个槽函数,可以被不同对象的信号关联
         第三个:同一个信号,可以关联多个不同的槽函数
                      多个槽函数的调用顺序跟你关联的先后顺序一致,先关联的先调用
         第四个:信号带参数,槽函数可以带参数,也可以不带参数
                      区别:槽函数带参数,参数类型,参数个数必须跟信号保持一致,表示槽函数接收信号传递过来的参数
                                槽函数不带参数,表示我不想接收信号传递过来的参数   

 同一个信号可以关联不同的槽函数

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //同一个信号clicked关联三个不同的槽函数
    connect(ui->bt,SIGNAL(clicked()),this,SLOT(fun3()));
    connect(ui->bt,SIGNAL(clicked()),this,SLOT(fun1()));
    connect(ui->bt,SIGNAL(clicked()),this,SLOT(fun2()));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::fun1()
{
    qDebug()<<"fun1调用了";
}

void MainWindow::fun2()
{
    qDebug()<<"fun2调用了";
}

void MainWindow::fun3()
{
    qDebug()<<"fun3调用了";
}

 同一个槽函数被不同的对象信号所关联

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //三个按钮共用一个槽函数
    connect(ui->bt1,SIGNAL(clicked()),this,SLOT(fun()));
    connect(ui->bt2,SIGNAL(clicked()),this,SLOT(fun()));
    connect(ui->bt3,SIGNAL(clicked()),this,SLOT(fun()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::fun()
{
    qDebug()<<"三个按钮其中一个按钮被点击了";
}

 信号带参数,槽函数带参数与不带参数

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //手动关联textChanged(const QString &text)信号
    //connect(ui->le,SIGNAL(textChanged(QString)),this,SLOT(fun()));
    connect(ui->le,SIGNAL(textChanged(QString)),this,SLOT(fun(QString)));
}

MainWindow::~MainWindow()
{
    delete ui;
}
//void MainWindow::fun()
void MainWindow::fun(QString arg)
{
    //qDebug()<<"信号有带参数,但是槽函数就不写参数,你能把我怎么样";
    qDebug()<<"信号有带参数,槽函数也带参数,参数是: "<<arg;
}

 5.获取信号的发送者
         作用:当多个组件对象共用一个槽函数的时候,程序员需要知道是哪个组件对象触发的信号,此时就要获取信号的发送者  
         QObject *sender() const
                    返回值:返回一个指针,该指针指向信号的发送者
         QT中转换函数(子类指向父类)
             qobject_cast(QObject *object)   //模板函数

 

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //三个按钮共用一个槽函数
    connect(ui->bt1,SIGNAL(clicked()),this,SLOT(fun()));
    connect(ui->bt2,SIGNAL(clicked()),this,SLOT(fun()));
    connect(ui->bt3,SIGNAL(clicked()),this,SLOT(fun()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::fun()
{
    //区分,判断究竟是哪个按钮触发了fun()
    //获取信号的发送者
    QPushButton *p=qobject_cast<QPushButton *>(sender());
    if(p==ui->bt1) //说明用户点击的是bt1
        qDebug()<<"用户点击的是按钮1";
    if(p==ui->bt2) //说明用户点击的是bt2
        qDebug()<<"用户点击的是按钮2";
    if(p==ui->bt3) //说明用户点击的是bt3
        qDebug()<<"用户点击的是按钮3";
}

 

两种实现UI界面的做法区别
=====================================
   1.哪两种实现UI的做法
               做法一:通过ui设计师界面直接拖组件过来
                                     QT会在构造函数的ui->setupUi(this);中帮你自动创建对象指针,并且分配堆空间(自动完成的)
                                     通过ui设计师界面直接拖组件过来使用的一定是堆空间
               做法二:程序员写代码,创建组件对象
                                     此时所有的组件都是你自己编写代码实现的,跟ui->setupUi(this)没有任何关系
                                     程序员自己编写代码创建对象无非就两种情况:
                                                  情况一:使用栈空间  QPushButton  mybt("登录",this);
                                                  情况二:使用堆空间  QPushButton  *mybt=new QPushButton("登录",this);

   2.这两种情况,我要使用组件对象,该如何使用??
                   通过ui设计师界面直接拖组件过来
                                   ui->组件对象指针->成员方法()
                                   比如:ui->pushButton->setFont(myfont);
                   程序员写代码,创建组件对象
                                   对象.成员方法()
                                   对象指针->成员方法()

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //在主窗口类的构造函数中,新建一个按钮对象
    QPushButton *mybt=new QPushButton("实现ui做法二:手动写代码创建了该按钮对象",this);
    //设置坐标,宽高
    mybt->setGeometry(200,300,300,70);

    //如何区分ui设计师拖过来的按钮,以及你自己手动创建的按钮

    //我要把ui拖过来的按钮字体设置成楷体 18号字
    QFont myfont("楷体",18);
    ui->pushButton->setFont(myfont);

    //我要把手动创建的按钮字体设置成楷体 18号字
    mybt->setFont(myfont);
}

MainWindow::~MainWindow()
{
    delete ui;
}

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hqb_newfarmer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值