zoukankan      html  css  js  c++  java
  • (三)信号与槽

     

    案列:

    1.点击button1改变button2的内容

    2.点击主窗口按钮,显示子窗口,再通过自定义信号与槽,点击子窗口,回到主窗口

    3.重载的信号槽

    4.拓展:

      1.信号可以连接信号

      2.一个信号可以连接多个槽函数

      3.多个信号可以连接一个槽函数

      4.槽函数可以使用lambda表达式

    例子:
    connect(operatorComboBox, QOverload<int>::of(&QComboBox::activated),
    this, &ImageComposer::recalculateResult);
    第二个参数需要一个信号(函数)的指针,但是QComboBox::activated实际上有两个重载函数
    void activated(const QString &text)
    void activated(int index)
    而上面的这种形式没有带形参列表,不知道返回第一个信号的指针还是第二个信号的指针
    这时候利用QOverLoad通过指定形参列表,来确定返回哪个信号的指针
    QOverload<int>::of()会返回一个函数指针
    所以其实QComBox::activated(int) 和 QOverload<int>::of(&QComboBox::activated)意思差不多

    mianwidget.cpp

    #include "mainwidget.h"
    #include <QDebug>
    
    MainWidget::MainWidget(QWidget *parent)
        : QWidget(parent)
    {
        // init
        b1 = new QPushButton("老大", this);
        b1->move(100, 100);
    
        b2 = new QPushButton;
        b2->setParent(this);
        b2->setText("老二");
        b2->move(200, 200);
    
        // b1 close window
        // qt 信号和槽他们都是函数
        // 1. 信号只有函数声明, 不需要函数定义
        // 2. 槽函数据需要声明也需要定义, 回调函数
        // connect(b1, &QPushButton::pressed, this, &MainWidget::close);
    
        // 自定义槽函数
        /*
         * 1. 槽函数在Qt5 可以是任意类成员函数, 全局函数, 静态函数, lambda表达式(隐式函数)
         * 2. 槽函数需要与信号对相应(返回值, 参数)
         * 3. 信号没有返回值, 槽函数返回值: void
         * 4. void mysig(int, double, QString);
         *    void myslot(int, double);
         * 5. 槽函数的参数是为了接受信号传过来的的数据
         * 6. 槽函数的参数应该是不能够大于信号的参数个数, 可以少于信号的参数个数
         * 7. 槽函数可以重载
        */
    
        connect(b1, &QPushButton::released, this, &MainWidget::slotForMianWidget);
    
    
        // b3 显示子窗口SubWidget  -- subW
        b3 = new QPushButton("软件园", this);
        b3->resize(100, 50);
        b3->move(200, 200);
    
        connect(b3, &QPushButton::clicked, this, &MainWidget::slotHideMe);
    
        // Qt 5 信号槽的使用方法
        void (SubWidget::*MySigSub)() = &SubWidget::sigSub;// 用函数指针来指定接收的信号是带参数还是不带参数
        connect(&subW, MySigSub, this, &MainWidget::slotShowMe);
    
        void (SubWidget::*MysigPlus)(int, QString) = &SubWidget::sigSub;// 用于信号函数发生重载的时候,告诉编译器调用哪个函数
        connect(&subW, MysigPlus, this, &MainWidget::slotSubMsg);
    
        // Q4 信号槽
        // SIGNAL() SLOT() 宏 将函数转换为字符串 宏展开预处理的时候不会报错
    //    connect(&subW, SIGNAL(sigSub()), this, SLOT(slotShowMe()));
    //    connect(&subW, SIGNAL(sigSub(int , QString)), this, SLOT(ABCDe(bb, aa)));
    
        // 使用lambda表达式作为槽函数
        connect(b1, &QPushButton::clicked, this, [=]()
        {
            b2->setText("lambda表达式!!!");
            b3->hide();
        });
    }
    
    MainWidget::~MainWidget()
    {
    
    }
    
    void MainWidget::slotForMianWidget()
    {
        b2->setText("我被老大改名了...");
    }
    
    void MainWidget::slotHideMe()
    {
        // 隐藏自己
        hide();
        // 显示软件园窗口
        subW.show();
    }
    
    void MainWidget::slotShowMe()
    {
        // 显示自己
        show();
        // 隐藏软件园窗口
        subW.hide();
    }
    
    void MainWidget::slotSubMsg(int num, QString str)
    {
        // QString --> char*
        // string --> char*   .data()
        qDebug() << num << str.toUtf8().data();
    
    }
    #ifndef MAINWIDGET_H
    #define MAINWIDGET_H
    
    #include <QWidget>
    #include <QPushButton>
    #include "subwidget.h"
    
    
    class MainWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        MainWidget(QWidget *parent = 0);
        ~MainWidget();
    
        // 自定义槽函数
        void slotForMianWidget();
        void slotHideMe();
        void slotShowMe();
        void slotSubMsg(int num, QString str);
    
    private:
        QPushButton* b1;
        QPushButton* b2;
        QPushButton* b3;    // 显示子窗口
        // 子窗口对象
        SubWidget subW;
    
    };
    
    #endif // MAINWIDGET_H
    mainwidget.h
    #include "subwidget.h"
    
    SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
    {
        b1= new QPushButton("中腾", this);
        b1->resize(100, 100);
    
        setWindowTitle("软件园窗口");
    
        resize(400, 600);
    
        connect(b1, &QPushButton::clicked, this, &SubWidget::myslot);
    }
    
    void SubWidget::myslot()
    {
        // 发送信号
        emit sigSub();
        emit sigSub(250, "你是二百五!!!");
    }
    subwidget.cpp

    subwidget.h

    #ifndef SUBWIDGET_H
    #define SUBWIDGET_H
    
    #include <QWidget>
    #include <QPushButton>
    
    class SubWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit SubWidget(QWidget *parent = 0);
    
    
    signals:
        // 自定义信号, 必须使用signals 声明
        void sigSub();
        void sigSub(int , QString);
        /*
         * 1. 可以有参数
         * 2. 可以重载
         * 3. 返回值为void
         * 4. 发送信号: emit + 信号名;
         * emit sigsub();
        */
    
    public slots:
        void myslot();
    
    private:
        QPushButton* b1;
    };
    
    #endif // SUBWIDGET_H
  • 相关阅读:
    [html]Sublime Text添加插件
    [C#.Net]判断文件是否被占用的两种方法
    C#中隐式运行CMD命令行窗口的方法
    [C#.Net]启动外部程序的几种常用方法汇总
    C# 管理员身份运行程序
    [C#.net]PostMessage与SendMessage的区别
    [C#.net] SendMessage
    由浅入深了解Thrift之客户端连接池化续
    由浅入深了解Thrift之客户端连接池化
    由浅入深了解Thrift之服务模型和序列化机制
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/10743857.html
Copyright © 2011-2022 走看看