QT 学习 (信号和槽)

首先看下信号和槽的连接函数


   
   
  1. QObject:: connect( const QObject *sender, const char *signal,
  2.                 const QObject *receiver, const char *method,
  3.                 Qt::ConnectionType type = Qt::AutoCompatConnection)

这是我们最常用的形式。connect() 一般会使用前面四个参数,第一个是发出信号的对象,第二个是发送对象发出的信号,第三个是接收信号的对象,第四个是接收对象在接收到信号之后所需要调用的函数。也就是说,当 sender 发出了 signal 信号之后,会自动调用 receiver 的 slot 函数。

其中最后一个参数是枚举类型定义了三种信号和槽的连接方式:

(1)  Qt::DirectConnection :信号发送后立即传递给相关联的槽函数,只有槽函数执行完毕返回后,发送信号"emit <信号>" 之后的代码才被执行

(2) Qt::QueuedConnection : 信号发送后排队,知道事件循环(event)有能力将它传递给槽; 而不管槽函数有没有执行,发送信号"emit <信号>" 之后的代码都会立即得到执行

(3) Qt::AutoConnection : 如果信号和槽函数在同一线程, 信号发出后,槽函数将立即执行, 等于Qt::DirectConnection;  如果信号和槽不在同一个线程,信号将排队,等待事件循环的处理,效果等同于Qt::QueuedConnection

一个类想支持信号和槽必须从QObject或QObject的子类继承。Qt信号和槽机制不支持对模板的使用

这两个东西说起来有点抽象,我还是不太明白;其实只要切实的去用过之后就会有一定的了解。

//connect() 第五个参数的作用, 连接方式: 默认,队列 ,直接
    //多线程才有用
    //默认的时候
    //多线程,默认使用队列
    //单线程,默认使用直接方式
    //队列:槽函数所在的线程和接收者一样(同类)
    //直接:槽函数所在线程和发送者一样(同类)

 

整理下Qt4和Qt5的信号和槽的连接方式

Qt4: 

      槽函数必须有 slots 关键字来修饰

       SIGNAL    SLOT将函数名字转换为字符串 不进行错误检查

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

 

Qt5:

(1) 自定义槽, 普通函数的用法

(2). 任意的成员函数,普通全局函数,静态函数

(3).  由于信号都是没有返回值,所以,槽函数一定没有返回值

connect(&button,  &QPushButton::pressed,  this,  &MainWidget::close);//连接信号和槽
/* &button:信号发出者,指针类型
* &QPushButton::pressed:处理的信号, &发送者的类名::信号名字
* &MainWidget::close: 槽函数, 信号处理函数 &接收的类名::槽函数名字
*/ 

   

       

 

 

一. 使用实例1.

源码下载:https://download.csdn.net/download/dianzishi123/10825578

在同一个类中定义一个私有槽函数和一个信号,这个信号只是在头文件(.h文件)中声明并没有真正的去实现这个信号;同样的在头文件中声明一个私有槽函数,在源文件(.cpp文件)中去实现这个槽函数某个功能,在一定条件下发射未实现的私有信号去触发这个槽函数也是可以得;总的来说就是只要声明一个信号就可以用来发射触发槽。

工程目录:

启动程序看下效果:

点击下按钮Button后效果:

工程中的相关文件

1. slotTest.pro文件:分别管理的是头文件(.h文件),源文件(.cpp文件)和相应的QT库


   
   
  1. SOURCES += \
  2. main.cpp \
  3. MyWidget.cpp
  4. HEADERS += \
  5. MyWidget.h
  6. QT += widgets gui

2. main.cpp文件: 主要是QT的事件循环和显示一个widget


   
   
  1. #include <QApplication>
  2. #include "MyWidget.h"
  3. int main(int argc, char** argv)
  4. {
  5. QApplication app(argc,argv);
  6. MyWidget s;
  7. s. show();
  8. return app. exec(); //qt事件循环
  9. }

3.MyWidget.cpp文件: 槽函数的实现, 构造函数中信号和槽的连接; 设置控件布局显示

整个过程是这样的:按下Button按钮后会有一个按钮事件clicked的信号产生,去触发这个点击事件的槽函数; 在这个槽函数会打印"button ......"信息并发射我自己声明的信号"mySignals"然后这个信号又会触发另一个槽函数,在这个槽函数中打印信息"mySignals......."


   
   
  1. #include "MyWidget.h"
  2. #include <QHBoxLayout>
  3. #include <QVBoxLayout>
  4. #include <QDebug>
  5. MyWidget:: MyWidget(QWidget *parent) : QWidget(parent)
  6. {
  7. QHBoxLayout *hlay = new QHBoxLayout;
  8. button = new QPushButton( this);
  9. button-> setText( "Button");
  10. lineEdit = new QLineEdit( this);
  11. hlay-> addStretch( 10); //加个弹簧
  12. hlay-> addWidget(lineEdit);
  13. hlay-> addWidget(button);
  14. hlay-> addStretch( 10);
  15. QVBoxLayout *vlay = new QVBoxLayout;
  16. vlay-> addLayout(hlay);
  17. this-> setLayout(vlay); //this指当前类也就是MyWidget类 把这个布局用到这个界面中
  18. //button 连接信号和槽
  19. connect( this->button, SIGNAL( clicked()), this, SLOT( mySlotButtonCliced()),Qt::AutoConnection);
  20. //自己定义的信号连接槽
  21. connect( this, SIGNAL( mySignals()), this, SLOT( mySlot()),Qt::AutoConnection); //因为信号和槽都是本类中的,直接用this
  22. }
  23. //button 关联的槽函数
  24. void MyWidget::mySlotButtonCliced()
  25. {
  26. qDebug()<< "button ...........";
  27. emit mySignals();
  28. }
  29. //自己定义信号mySignals关联的槽函数
  30. void MyWidget::mySlot()
  31. {
  32. qDebug()<< "mySignals..........";
  33. }

4. MyWidget.h文件: 实现槽和信号的声明,和一些变量声明


   
   
  1. #ifndef MYWIDGET_H
  2. #define MYWIDGET_H
  3. #include <QWidget>
  4. #include <QPushButton>
  5. #include <QLineEdit>
  6. class MyWidget : public QWidget
  7. {
  8. Q_OBJECT
  9. public:
  10. explicit MyWidget(QWidget *parent = nullptr);
  11. signals: //信号的声明不区分public和private
  12. void mySignals();
  13. private slots:
  14. void mySlotButtonCliced();
  15. void mySlot();
  16. private:
  17. QPushButton *button;
  18. QLineEdit *lineEdit;
  19. public slots:
  20. };
  21. #endif // MYWIDGET_H

 

 

 

 

 

二. 自定义信号和槽函数传参数问题

在声明信号时, 添加有参数的信号, 在通过emit发射信号时把相应的参数传递给信号, 相关联的槽函数也有相同的参数,这样就把信号的参数,传递给槽函数了....................................................还未完....................

 

 

 

 

 

 

 

 

 

 

 

总结思考:

1. 私有的槽和信号是否只能在本类中使用;

2. 公有槽和信号是否可以实现不同类之间的通信

3. 感觉好灵活...

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT 5.12版本中信号的使用方式有所改变。在以前的版本中,我们可以使用connect函数来连接信号,例如connect(sender, SIGNAL(signal()), receiver, SLOT(slot()))。但在QT 5.12版本中,SIGNAL和SLOT宏已经不再需要使用了。 在QT 5.12版本中,我们可以使用新的语法直接连接信号。例如,如果我们有一个按钮m_applyBtn,并且想在按钮按下时执行一个函数onApplyBtnPressedSlt,我们可以这样做: ```cpp connect(m_applyBtn, &QPushButton::pressed, this, &MyClass::onApplyBtnPressedSlt); ``` 这,&QPushButton::pressed表示按钮按下的信号,this表示接收信号的对象(一般是当前类的实例),&MyClass::onApplyBtnPressedSlt表示要执行的函数。 同样地,如果我们有另一个按钮m_backBtn,并且想在按钮按下时执行另一个函数onBackBtnPressedSlt,我们可以使用以下代码进行连接: ```cpp connect(m_backBtn, &QPushButton::pressed, this, &MyClass::onBackBtnPressedSlt); ``` 这样,按钮的pressed信号就会触发相应的函数。 需要注意的是,在新的语法中,信号的参数类型必须一致。如果信号的参数不一致,可以使用QOverload和QMetaObject::Connection来解决这个问题。但这超出了本次讨论的范围。 总结起来,QT 5.12版本中,我们可以使用新的语法直接连接信号,不再需要使用SIGNAL和SLOT宏。使用新的语法可以提供更好的类型安全性和编译时错误检查。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [QT5.12中的信号问题](https://blog.csdn.net/bxlover007/article/details/116204430)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [QT C++学习代码案例](https://download.csdn.net/download/m0_73878864/88259441)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值