当前位置: 首页 > article >正文

QT:详解信号和槽

写在前面的话:
在widget.h中的这个Q_OBJECT这个类是无论如何不能去掉的
去掉这个,我们的代码基本上就无法编译通过!
在这里插入图片描述

文章目录

  • 1.文本编辑框
  • 2.按钮
    • 2.1 控件生成
    • 2.2 代码生成
  • 3.查询快捷键和文档的方式
  • 4.QT窗口坐标体系
  • 5.信号和槽
    • 5.1 connect函数
    • 5.2 自定义槽函数
      • 5.2.1 通过代码自定义槽函数
      • 5.2.2 通过控件自定义槽函数
    • 5.3 自定义信号
    • 5.4 带参数的信号槽
    • 5.5 信号和槽存在的意义
    • 5.6 信号和槽断开连接
    • 5.7 使用lambda表达式定义槽函数


1.文本编辑框

在这里插入图片描述

2.按钮

2.1 控件生成

在这里插入图片描述

2.2 代码生成

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void handleClick();
    void handleClick2();

private:
    Ui::Widget *ui;
    QPushButton* mybutton;
};
#endif // WIDGET_H

widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include<QLineEdit>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QLineEdit* edit=new QLineEdit(this);
    edit->setText("Hello QT!");

    //利用QT中的槽机制给按钮的点击操作,关联上一个处理函数
    connect(ui->aa,&QPushButton::clicked,this,&Widget::handleClick);

    mybutton=new QPushButton(this);//这里不能QPushButton* mybutton,函数内部的成员变量不能跨函数访问,添加到头文件中的private中即可!
    mybutton->setText("这是第二个代码写的按钮!");
    connect(mybutton,&QPushButton::clicked,this,&Widget::handleClick2);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::handleClick()
{
    //当按钮被点击后,就把按钮中的文本进行切换
    if(ui->aa->text()==QString("Hello mybutton"))
    {
        ui->aa->setText("我是帅哥!");
    }
    else {
    ui->aa->setText("Hello mybutton");
    }
}

void Widget::handleClick2()
{
    //当按钮被点击后,就把按钮中的文本进行切换
    if(mybutton->text()==QString("这是第二个代码写的按钮!"))
    {
        mybutton->setText("代码写得第二个按钮变化!!");
    }
    else {
    ui->aa->setText("这是第二个代码写的按钮!");
    }
}

在这里插入图片描述
这里第二个按钮覆盖了第一个文本框(控件怎么移动见本篇文章第四部分),这里我们就先看一下效果就行,这些东西怎么处理后面再说!

提示:我们可以发现咱们已经不需要自己new对象了,new已经被QT自动生成了,而且这个按钮对象已经作为ui对象里的一个成员变量了!!!也无需作为Widget的成员!!

3.查询快捷键和文档的方式

Qt Creator 中的快捷键
• 注释:ctrl + /
• 运⾏:ctrl + R
• 编译:ctrl + B
• 字体缩放:ctrl+ ⿏标滑轮
• 查找:ctrl + F
• 整⾏移动:ctrl + shift + ⬆/⬇
• 帮助⽂档:F1
• ⾃动对⻬:ctrl + i;
• 同名之间的 .h 和 .cpp 的切换:F4
• ⽣成函数声明的对应定义: alt + enter

查询文档只要有三种方式:
1、光标放到要查询的类名/⽅法名上, 直接按 F1
2.Qt Creator 左侧边栏中直接⽤⿏标单击 “帮助” 按钮: 在这里插入图片描述
3.找到 Qt Creator 的安装路径,在 “bin” ⽂件夹下找到 assistant.exe,双击打开(即使用手册);
在这里插入图片描述

4.QT窗口坐标体系

在这里插入图片描述
上面第二部分的代码有一部分被挡住了,我们可以修改它,让他移动,以哦对那个后就不被遮挡了
在这里插入图片描述

在这里插入图片描述

5.信号和槽

槽就相当于一个函数,但又大于函数
前面我们使用的connect这样的函数就是,把一个信号和一个槽关联起来!!只要信号触发了,QT就会自动的执行槽函数!槽函数本质上已是一种回调函数!
提示:QT中,一定是先关联信号和槽,然后再触发这个信号。顺序不能颠倒,否则信号就不知道如何处理了!!

5.1 connect函数

QObject提供的静态的成员函数。

下面是一个点击按钮就关闭窗口的例子
以及connect函数的详细解释:
在这里插入图片描述
在这里插入图片描述

5.2 自定义槽函数

5.2.1 通过代码自定义槽函数

所谓的自定义一个槽函数,操作过程和自定义一个普通的成员函数没啥区别。
在这里插入图片描述
在这里插入图片描述

5.2.2 通过控件自定义槽函数

在这里插入图片描述
但是这样有一个问题,我们发现自动生成的代码中没有connect函数
在这里插入图片描述
如果我们通过图形化界面创建控件,还是推荐第二种这种方式快速连接信号槽。
如果我们是通过代码的方式来创建控件,还是得手动connect!

5.3 自定义信号

自定义信号比较少见,实际开发中很少会需要自定义信号。
QT内置的信号,已经基本覆盖到了所有可能的用户操作。
所谓的QT“信号”本质上也就是一个函数。QT5及更高版本中,槽函数和普通的成员函数之间就已经没啥区别了!
但是,信号,是一个非常特殊的函数。程序员只需要写出函数声明,并告诉QT这是一个信号即可!这个函数的定义是QT在编译过程中自动生成的。
作为信号函数,这个函数的返回值必须是void,有没有参数都可以,甚至也可以支持重载!
在这里插入图片描述

5.4 带参数的信号槽

当信号带有参数的时候,槽的参数必须和信号参数一致!
此时发射信号的时候,就可以给信号函数传递实参,与之对应的这个参数就被传递到对应的槽函数中。
在这里插入图片描述
信号函数的参数个数,超过了槽函数的参数个数,是可以正常运行的!!

但是,信号函数的参数个数少于槽函数的参数个数,此时代码无法编译通过!!

对于参数类型必须要满足以下条件:
在这里插入图片描述

5.5 信号和槽存在的意义

信号槽终究要解决的问题就是响应用户的操作!!
在这里插入图片描述

5.6 信号和槽断开连接

也就是使用disconnect来断开信号槽的连接。
disconnect和connect是非常相似的,disconnect用的比较少,大部分情况下连接上之后就不用管了,除非需要断开重新绑定到另一个槽函数上。
不解绑就有可能会造成一对多的情况,即一个信号触发多个槽函数!!

connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick);
disconnect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick2);

5.7 使用lambda表达式定义槽函数

lambda表达式本质就是一个匿名函数,主要应用在回调函数场景中,一次性使用。
在这里插入图片描述

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QPushButton* lambda_button=new QPushButton(this);
    lambda_button->setText("按钮");
    lambda_button->move(50,100);

    connect(lambda_button,&QPushButton::clicked,this,[=](){
        qDebug()<<"lambda已经执行!";
        lambda_button->move(200,200);
        this->setWindowTitle("我也变变!");
    });
}

在这里插入图片描述
注意,lambda表达式是C++11引入的,对于QT5以及更高版本,默认采用C++11编译,但是QT4及以下需要手动在.pro文件中加上C++11的编译选项(CONFIG += c++11)


http://www.kler.cn/news/285317.html

相关文章:

  • 相机坐标系转换世界坐标系,zedimudepth
  • 【C++ 第十八章】C++11 新增语法(4)
  • BMC lighttpd kvm数据分析(websocket)
  • 【Qt笔记】QCommandLinkButton控件详解
  • Unity编辑器扩展之Scene视图扩展
  • Windows Edge浏览器对Web Authentication API的支持分析与实践应用
  • 音频处理新纪元:深入探索PyTorch的torchaudio
  • vue新建按钮弹出选框
  • 【第0004页 · 递归】生成括号对
  • 缓存Mybatis一级缓存与二级缓存
  • 【Java设计模式】数据总线模式:高效统一组件通信
  • 【鬼灭之刃学英语 立志篇】2、义勇对炭治郎的怒斥
  • 4.1 版本管理器——2PL与MVCC
  • 第 20 章 DOM 进阶
  • 应用层协议(下)Https加密Http的秘密(含逻辑图解 简单易学 通俗易懂!)
  • DataSet和DataTable的关系
  • Python爬虫所需的技术及其原理(简单易懂)
  • 策略模式+模版方法模式+简单工厂模式混用优化代码复杂分支问题
  • 【软件测试】bug以及测试用例的设计方法
  • Taro 微信小程序 分页上拉加载
  • C语言程序设计(初识C语言后部分)
  • Java—可变参数、不可变集合
  • 单链表应用
  • 在Jtti服务器上怎么安装和配置Docker?
  • Pandas 绘图的强大之处:后端
  • Vue面试常见知识总结2——spa、vue按需加载、mvc与mvvm、vue的生命周期、Vue2与Vue3区别
  • 鸿蒙OS试题(6)
  • 自动驾驶---什么是Frenet坐标系?
  • AI学习指南深度学习篇-门控循环单元中的门控机制
  • jenkins发送html邮件配置步骤与注意事项?