【小沐学QT】QT学习之信号槽使用

2024-02-29 1026阅读

温馨提示:这篇文章已超过388天没有更新,请注意相关的内容是否还可用!

文章目录

  • 1、简介
  • 2、代码实现
    • 2.1 界面菜单“转到槽”方法
    • 2.2 界面信号槽编辑器方法
    • 2.3 QT4.0的绑定方法
    • 2.4 QT5.0之后的绑定方法
    • 2.5 C++11的方法
    • 2.6 lamda表达式方法
    • 结语

      1、简介

      在GUI编程中,当我们更改一个小部件时,我们通常希望通知另一个小程序。更普遍地说,我们希望任何种类的物体都能够相互通信。例如,如果用户单击“关闭”按钮,我们可能希望调用窗口的Close()函数。

      【小沐学QT】QT学习之信号槽使用

      其他工具包使用回调实现这种通信。回调是指向函数的指针,因此,如果您希望处理函数通知您某个事件,您可以将指向另一个函数的指针(回调)传递给处理函数。然后,处理函数在适当的时候调用回调。虽然使用这种方法的成功框架确实存在,但回调可能是非直观的,并且在确保回调参数的类型正确性方面可能会遇到问题。

      【小沐学QT】QT学习之信号槽使用

      在Qt中,我们有一种替代回调技术的方法:我们使用信号和槽。当特定事件发生时,会发出一个信号。Qt的小部件有许多预定义的信号,但我们总是可以对小部件进行子类化,以向它们添加我们自己的信号。槽是响应于特定信号而调用的函数。Qt的小部件有许多预定义的插槽,但通常的做法是对小部件进行子类化,并添加自己的插槽,以便处理您感兴趣的信号。

      【小沐学QT】QT学习之信号槽使用

      信号与槽是用于对象之间的通信的,这是 Qt 的核心。为此 Qt 引入了一些关键字,他们是slots、signals、emit,这些都不是 C++关键字,是 Qt 特有的,这些关键字会被 Qt 的 moc转换为标准的 C++语句。

      • 连接规则:

        1、信号参数可以比槽函数多,反之则不可以

        2、 一个信号可以连接多个槽

        3、多个信号可以连接到一个槽

        4、一个信号可以与另一个信号连接

        2、代码实现

        2.1 界面菜单“转到槽”方法

        在按钮上鼠标右键弹出菜单,选择“转到槽…”,如下:

        【小沐学QT】QT学习之信号槽使用

        弹出小窗口,选择“clicked()”后确定。

        【小沐学QT】QT学习之信号槽使用

        然后在文件里自动生成代码如下:

        • mainwindow.h
          private slots:
              void on_pushButton_clicked();
          
          • mainwindow.cpp
            void MainWindow::on_pushButton_clicked()
            {
                QMessageBox::information(this, "", "on_pushButton_clicked");
            }
            

            2.2 界面信号槽编辑器方法

            打开信号槽编辑界面,添加记录,设置相关参数。

            【小沐学QT】QT学习之信号槽使用

            在mainwindow.ui界面定义文件中会自动生成对应的代码,可以手动修改。

            【小沐学QT】QT学习之信号槽使用

            2.3 QT4.0的绑定方法

            Qt4使用了SIGNAL和SLOT这两个宏,将信号和槽的函数名转换成了字符串。使用字符串导致了Qt4有以下缺点:一旦出现连接不成功的情况,Qt 4 是没有编译错误的

            connect(obj1, SIGNAL(fun1(param1, param2,...)), obj2, SLOT(fun2(param1,...)));
            

            优点:对所有控件都适用。

            缺点:书写繁琐,槽函数必须在slots标签下。

            (1)和控件有关系的信号槽

            • mainwindow.h
              private slots:
                  void pushButon1_clicked();
              
              • mainwindow.cpp
                MainWindow::MainWindow(QWidget *parent)
                    : QMainWindow(parent)
                    , ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(pushButon1_clicked()));
                }
                void MainWindow::pushButon1_clicked()
                {
                    QMessageBox::information(this, "", "pushButon1_clicked");
                }
                

                (2)和控件无关系的信号槽

                • mainwindow.h
                  signals: //信号:
                      void mySignal_1(int a);
                  	void mySignal_2(int a, float b);
                  private slots: //槽:
                      void mySlot_1(int b);
                      void mySlot_2(int b);
                  
                  • mainwindow.cpp
                    MainWindow::MainWindow(QWidget *parent)
                        : QMainWindow(parent)
                        , ui(new Ui::MainWindow)
                    {
                        ui->setupUi(this);
                    	
                    	//信号槽:
                        connect(this,SIGNAL(mySignal_1(int)),this,SLOT(mySlot_1(int)));
                    	connect(this, SIGNAL(mySignal_2(int, float)), this, SLOT(mySlot_2(int)));
                    }
                    void MainWindow::mySlot_1(int b)
                    {
                        QString str = QString::number(b);
                        QMessageBox::information(this, "1", str);
                    }
                    void MainWindow::mySlot_2(int b)
                    {
                        QString str = QString::number(b);
                        QMessageBox::information(this, "2", str);
                    }
                    void MainWindow::test()
                    {
                    	//发送信号:
                    	emit mySignal_2(5, 2.2);
                        emit mySignal_1(123);
                    }
                    

                    注意:在不进行参数传递时,信号槽绑定时也是要求信号的参数数量大于等于槽函数的参数数量。这种情况一般是一个带参数的信号去绑定一个无参数的槽函数。

                    2.4 QT5.0之后的绑定方法

                    • mainwindow.cpp
                      MainWindow::MainWindow(QWidget *parent)
                          : QMainWindow(parent)
                          , ui(new Ui::MainWindow)
                      {
                          ui->setupUi(this);
                          connect(ui->pushButton,&QPushButton::clicked,this,&::MainWindow::pushButon1_clicked);
                      }
                      void MainWindow::pushButon1_clicked()
                      {
                          QMessageBox::information(this, "", "pushButon1_clicked");
                      }
                      

                      connect()函数基于函数指针的重载形式:

                      [static] QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, 
                      const QObject *receiver,
                      PointerToMemberFunction method,
                      Qt::ConnectionType type = Qt::AutoConnection)
                      

                      注意:这是QT5中加入的一种重载形式,指定信号和槽两个参数不再使用SIGNAL()和 SLOT()宏,并且槽函数不再必须是使用slots关键字声明的函数,可以是任意能和信号关联的成员函数。要使一个成员函数可以和信号关联,那么这个函数的参数数目不能超过信号的参数数目,但是并不要求该函数拥有的参数类型和信号中对应的参数类型完全一致,只需要可以进行隐式转换即可。

                      connect(dlg, &myWindwow::test1, this, &myWidget::test2);
                      

                      2.5 C++11的方法

                      • mainwindow.cpp
                        MainWindow::MainWindow(QWidget *parent)
                            : QMainWindow(parent)
                            , ui(new Ui::MainWindow)
                        {
                            ui->setupUi(this);
                            connect(ui->pushButton, QOverload::of(&QPushButton::clicked),this,&::MainWindow::pushButon1_clicked);
                        }
                        void MainWindow::pushButon1_clicked()
                        {
                            QMessageBox::information(this, "", "pushButon1_clicked");
                        }
                        

                        2.6 lamda表达式方法

                        还支持C++11 中的lambda表达式,可以在关联时直接编写信号发射后要执行的代码。

                        connect(dlg, &MyWindow::test1, [ = ](int value){
                        	ui->label->setText(tr("获取的值是:%1"),arg(value));
                        });
                        
                        • mainwindow.cpp
                          MainWindow::MainWindow(QWidget *parent)
                              : QMainWindow(parent)
                              , ui(new Ui::MainWindow)
                          {
                              ui->setupUi(this);
                              connect(ui->pushButton, QOverload::of(&QPushButton::clicked),[=](){
                                    QMessageBox::information(this, "", "lamda表达式绑定成功!");
                              });
                          }
                          

                          MainWindow::MainWindow(QWidget *parent)
                              : QMainWindow(parent)
                              , ui(new Ui::MainWindow)
                          {
                              ui->setupUi(this);
                              connect(ui->pushButton, &QPushButton::clicked, this, [=](){
                                     QMessageBox::information(this, "", "lamda表达式绑定成功2!");
                              });
                          }
                          

                          结语

                          如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭

                          如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???

                          如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)

                          感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]