zoukankan      html  css  js  c++  java
  • Qt5------信号和槽函数

    信号:

      * 信号必学用signals关键字来声明,signals是Qt拓展的关键字
      * 信号没有返回值,但可以有参数
      * 信号就是函数声明,只需声明,无需定义
      * 使用: emit mySignal();
      * 信号可以重载

      使用connec进行从指定类型将信号发送给接受对象的方法的链接,例如:

    connect(&b1,&QPushButton::pressed,this,&MyWidget::close);
    /*参数:
    *    &b1:信号发出者,指针类型
    *     &QPushButton:pressed:处理的信号,&发送者的类名::信号名字
    *     this:信号接受者
    *     &MyWidget::close:槽函数,即信号处理函数,&接受的类名::槽函数
    */

    自定义槽函数:
      * Qt5:任意成员函数,普通全局函数,静态函数
      * 槽函数需要和信号一致(参数,返回值)
      * 由于信号没有返回值,所以,槽函数一定没有返回值,例如:

    connect(&b2,&QPushButton::released,this,&MyWidget::mySlot);
    //槽函数
    void MyWidget::mySlot()
    {
        //b2是一个QPushButton类型
        b2.setText("123");
    }

    无参数信号:
      例如:

    //定义一个信号
    signals:
        void mySignal();
    //使用信号
    void SubWidget::sendSlot()
    {
        emit mySignal();
    }

    信号和槽函数使用示例:

      功能:切换窗口,并隐藏当前窗口
    主窗口

    class MyWidget : public QWidget
    {
    Q_OBJECT
    
    public:
        MyWidget(QWidget *parent = 0);
        void mySlot();
        void changeWin();
        void dealSub(void);
        ~MyWidget();
    private:
        QPushButton b1; //窗口关闭按钮
        QPushButton b3; //切换窗口按钮
        SubWidget w; //另一独立窗口
    };

    方法实现:

    MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent),b1(this)
    {
        b1.setText("close");
        b1.move(100,100);
        connect(&b1,&QPushButton::pressed,this,&MyWidget::close);
        setWindowTitle("老大");//设置窗口标题
        b3.setParent(this); //绑定父对象
        b3.setText("切换到子窗口");
        b3.move(50,50);
        connect(&b3,&QPushButton::released,this,&MyWidget::changeWin);
        connect(&w,&SubWidget::mySignal,this,&MyWidget::dealSub);
    }
    void MyWidget::dealSub()
    {
        w.hide();
        this->show();
    }
    void MyWidget::changeWin()
    {
        w.show();
        this->hide();
    }
    MyWidget::~MyWidget(){}

    第二个窗口:

    class SubWidget : public QWidget
    {
    Q_OBJECT
    public:
        explicit SubWidget(QWidget *parent = nullptr);
        void sendSlot();//槽函数
    signals:
        void mySignal();
    public slots:
    private:
        QPushButton b1;//切换窗口按钮
    };

    方法实现:

    SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
    {
        this->setWindowTitle("小弟");
        b1.setParent(this);
        b1.setText("切换到主窗口");
        //当按键按下时产生信号,调用sendSlot发送信号mySignal()
        connect(&b1,&QPushButton::clicked,this,&SubWidget::sendSlot);
    }
    void SubWidget::sendSlot()
    {
        emit mySignal();
    }

    有参数的信号:
    信号重载后,会照成二义性问题,信号和槽函数必须一制,即参数列表类型和顺序一样,但参数个数可以不一样(Ps:信号的参数个数大于等于槽函数参数个数,反之不可)。
    信号:

    void mySignal(int,QString);
    emit mySignal(250,"我是子窗口");

    槽函数:

    void MyWidget::dealSlot(int a,QString str)
    {
        //str.toUtf8()转换成字节数组QByteArray
        //.............data() 转换成char*
        qDebug() << a << str.toUtf8().data();
    }

    解决方法如下:
    1.通过不同的函数指针,区分接收到的信号

    void (SubWidget::*funSignal)() = &SubWidget::mySignal;
    void (SubWidget::*testSignal)(int,QString) = &SubWidget::mySignal;
    connect(&w,funSignal,this,&MyWidget::dealSub);
    connect(&w,testSignal,this,&MyWidget::dealSlot);

    2.使用Qt4中的方法:
      * Qt4槽函数必须有slots关键字修饰
      * 缺陷:SIGNAL SLOT 将函数名字转换成字符串,不进行错误检查
      * 建议:使用Qt5的处理方法
    类中定义:

    ......
    public slots:
        void mySlot();
        void changeWin();
        void dealSub();
        void dealSlot(int,QString);
    ......

    函数实现中应用:

    ......
    connect(&w,SIGNAL(mySignal(int,QString)),this,SLOT(dealSlot(int,QString)));
    connect(&w,SIGNAL(mySignal()),this,SLOT(dealSub()));
    ......

    Lambda表达式:匿名函数对象
    * C++11新增加的特性,配合信号使用,非常方便
    * 需要在项目文件添加:CONFIG += C++11

    QPushButton *b4 = new QPushButton(this);
    b4->setText("Lambda表达式");
    b4->move(150,150);
    int a=10,b=100;
    /*
    * []用来传递外部参数,
    * = :把外部所有局部变量,类中所有成员以值传递方式,但是是只读的,使用mutable改变,
    * this:类中所有成员以值传递方式
    * & :把外部所有局部变量以值传递方式,避免使用
    * () :接受到的参数
    */
    connect(b4,&QPushButton::clicked,
        [=](bool isCheck)mutable
        {
            qDebug() << "111111";
            qDebug() << a << b;
            qDebug() << isCheck;
            a = 11;
        }
    );                

    *是在上面示例程序中的信号(我自己理解的,如有错误,还请指出)
    released():当按键释放时产生
    pressed() :当按键按下时产生
    clicked(bool checked = false) :当按键被激活时产生(按钮被按下,然后释放)

  • 相关阅读:
    安卓界面基本组件------计时器
    安卓界面组件----时间日期拾取器
    安卓界面组件----列表视图
    安卓组件------列表选择框
    Redis 开启远程访问
    收集的一个关于大批量插入数据的代码
    Server.MapPath和Request.PhysicalApplicationPath的异同
    C#中使用正则表达式验证电话号码、手机号、身份证号、数字和邮编
    cocos2d-x3.2在xcode6.1下的 环境搭建
    STL源码剖析(适配器)
  • 原文地址:https://www.cnblogs.com/zhangzeze/p/9134033.html
Copyright © 2011-2022 走看看