QT_基础

一、对象模型

  • 信号槽

    • 概念

  信号和槽用于两个对象之间的通信,信号和槽机制是Qt的核心特征,也是Qt不同于其他开发框架的最突出的特征。

  一个信号可以关联到多个槽上,多个信号也可以关联到同一个槽上,甚至,一个信号还可以关联到另一个信号上。如果存在多个槽与某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地执行,执行顺序与关联顺序相同。

image

    •  信号关联多个槽时,槽函数的执行顺序

      • 在Qt4版本里面,当信号被触发时,会依次随机调用,即本次信号会把与信号关联的所有的槽函数都调用一遍,但顺序是随机的;

      • 在Qt5版本里面,则与关联信号的顺序有关,调用顺序与关联顺序一致。

    • 语法

      • 信号

      • 声明一个信号,例如:
        signals:
            void dlgReturn(int);       // 自定义的信号
        
        声明一个信号要使用signals关键字。
        在signals前面不能使用public、private和protected等限定符,因为只有定义该信号的类及其子类才可以发射该信号。
        信号只用声明,不需要也不能对它进行定义实现。
        信号没有返回值,只能是void类型的。
        只有QObject类及其子类派生的类才能使用信号和槽机制,使用信号和槽,还必须在类声明的最开始处添加Q_OBJECT宏。
      • 发射信号

      • 例如:
        void MyDialog::on_pushButton_clicked()   // 确定按钮
        {
            int value = ui->spinBox->value();    // 获取输入的数值
            emit dlgReturn(value);               // 发射信号
            close();                             // 关闭对话框
        }
        
        当单击确定按钮时,便获取spinBox部件中的数值,然后使用自定义的信号将其作为参数发射出去。发射一个信号要使用emit关键字,例如程序中发射了dlgReturn()信号。
      • 自定义槽的声明:
        private slots:
            void showValue(int value);
        实现:
        void Widget::showValue(int value)         // 自定义槽
        {
            ui->label->setText(tr("获取的值是:%1").arg(value));
        }
        
            声明一个槽需要使用slots关键字。一个槽可以是private、public或者protected类型的,槽也可以被声明为虚函数,这与普通的成员函数是一样的,也可以像调用一个普通函数一样来调用槽。槽的最大特点就是可以和信号关联。
      • 信号和槽的关联

        • 第一种写法
        • connect(this, SIGNAL(dlgReturn(int)),SLOT(showValue(int)));

          image

          connect()函数的最后一个参数,它表明了关联的方式,其默认值是Qt::AutoConnection,这里还有其他几个选择,具体功能如下表所示

        • image

        • 第二种写法
        • connect(this, &SignalSlot::dlgReturn, this, &SignalSlot::showValue);
           
          使用这种方式与前一种相比,还有一个好处就是可以在编译时进行检查,信号或槽的拼写错误、槽函数参数数目多于信号的参数数目等错误在编译时就能够被发现。 
        • 第三中写法
        • connect(this, &SignalSlot::dlgReturn, this, [=]{
                  ui->label->setText(tr("获取的值时:%1").arg(99));
              });
          匿名函数
      • 信号和槽的自动关联

          它由“on”、部件的objectName和信号三部分组成,中间用下划线隔开。这样组织的名称的槽就可以直接和信号关联,而不用再使用connect()函数

      • 信号槽的高级应用

        • 有时希望获得信号发送者的信息,在Qt中提供了QObject::sender()函数来返回发送该信号的对象的指针。

           

        • 但是如果有多个信号关联到了同一个槽上,而在该槽中需要对每一个信号进行不同的处理,使用上面的方法就很麻烦了。对于这种情况,便可以使用QSignalMapper类。QSignalMapper可以被叫做信号映射器,它可以实现对多个相同部件的相同信号进行映射,为其添加字符串或者数值参数,然后再发射出去

      • 示例

      • //SignalSlot.h
        
        
        #ifndef SIGNALSLOT_H
        #define SIGNALSLOT_H
        
        #include <QWidget>
        
        namespace Ui {
        class SignalSlot;
        }
        
        class SignalSlot : public QWidget
        {
            Q_OBJECT
        
        public:
            explicit SignalSlot(QWidget *parent = 0);
            ~SignalSlot();
        
        private:
            Ui::SignalSlot *ui;
        
        private slots:
            void showValue(int value);
        
            void on_pushButton_clicked();
        
        signals:
            void dlgReturn(int);
        };
        
        #endif // SIGNALSLOT_H
        
        
        
        //SignalSlot.cpp
        #include "signalslot.h"
        #include "ui_signalslot.h"
        
        
        SignalSlot::SignalSlot(QWidget *parent) :
            QWidget(parent),
            ui(new Ui::SignalSlot)
        {
            ui->setupUi(this);
            //第一种写法
            connect(this, SIGNAL(dlgReturn(int)),SLOT(showValue(int)));
            //第二种写法
            //connect(this, &SignalSlot::dlgReturn, this, &SignalSlot::showValue);
            //第三中写法
            connect(this, &SignalSlot::dlgReturn, this, [=]{
                ui->label->setText(tr("获取的值时:%1").arg(99));
        
        
            });
        }
        
        
        SignalSlot::~SignalSlot()
        {
            delete ui;
        }
        
        
        void SignalSlot::showValue(int value)
        {
            ui->label->setText(tr("获取的值时:%1").arg(value));
        }
        
        
        void SignalSlot::on_pushButton_clicked()
        {
            int value = ui->spinBox->value();
            emit dlgReturn(value);
            //close();
        }
        
        
         

二、事件模型

 在Qt中,事件作为一个对象,继承自QEvent类,常见的有键盘事件QKeyEvent、鼠标事件QMouseEvent和定时器事件QTimerEvent等,它们与QEvent类的继承关系如图所示

image

 

posted @ 2025-10-21 22:48  直至成伤  阅读(2)  评论(0)    收藏  举报