美文网首页Qt学习C++程序员
2.3信号和槽(上)

2.3信号和槽(上)

作者: 223480235e8e | 来源:发表于2017-08-29 08:14 被阅读264次

如果面试官问你Qt最明显区别于其它开发框架的特征是什么,那么你的回答一定是信号和槽,为此,小豆君将拿出三节的时间来讲述信号和槽。

第一节,信号槽的基本概念。
第二节,信号槽的扩展知识。
第三节,分析Qt的moc预编译器生成的moc源文件,帮助大家理解信号槽的来龙去脉。

2.3.1 引子

在面向对象的编程方法中,都会创建很多的实例,每个实例都是单独的,要想每个实例能够协同合作,那么就会需要一种对象间传递消息的机制,在很多框架中都采用回调函数来进行对象间信息传递。

回调是一个指向函数的指针,如果想要一个处理函数通知一些事件,你需要将这个指针传递给处理函数。处理函数在适当时间调用回调函数。MFC就是使用的回调函数,但回调可能是不直观的,不易于理解的,并且也不能保证是类型安全的。

Qt为了消除回调函数等的弊端,从而Qt开发了一种新的消息传递机制,即信号和槽。

例如,当我们要求鼠标点击某个按钮时,对应的窗口就需要关闭,那么这个按钮就会发出一个关闭信号,而窗口接收到这个信号后执行关闭窗口。那么,这个信号就是按钮被点击,而槽就是窗口执行关闭函数。

可以将信号和槽理解成“命令-执行”,即信号就是命令,槽就是执行命令。


Paste_Image.png

2.3.2 信号

当一个对象的内部状态发生改变时,如果其它对象对它的状态需要有所反应,这时就应该让这个类发出状态改变的信号。

声明信号使用signals关键字

发送信号使用emit关键字

注意:

1.所有的信号声明都是公共的,所以Qt规定不能在signals前面加public,private, protected。
2.所有的信号都没有返回值,所以返回值都用void。
3.所有的信号都不需要定义。
4.必须直接或间接继承自QOBject类,并且开头私有声明包含Q_OBJECT。
5.当一个信号发出时,会立即执行其槽函数,等待槽函数执行完毕后,才会执行后面的代码,如果一个信号链接了多个槽,那么会等所有的槽函数执行完毕后才执行后面的代码,槽函数的执行顺序是按照它们链接时的顺序执行的。
6.在链接信号和槽时,可以设置链接方式为:在发出信号后,不需要等待槽函数执行完,而是直接执行后面的代码。
7.发出信号使用emit关键字。
8.信号参数的个数不得少于槽参数的个数。

2.2.3 槽

槽其实就是普通的C++函数,它唯一特点就是能和信号链接。当和它链接的信号被发出时,这个槽就会被调用。

声明槽可以使用:public/protected/private slots:

以上是Qt4的做法,在Qt5中你也不需要使用这些声明,每个函数都可以被当作是槽函数,而且还可以使用Lambda表达式来作为槽。不过为了程序的可读性,我还是推荐槽函数要声明一下。

2.2.4连接信号和槽

使用connect函数连接信号和槽

2.2.4.1 原型1

static QMetaObject::Connection connect(
    const QObject *sender, //信号发送对象指针
    const char *signal,    //信号函数字符串,使用SIGNAL()
    const QObject *receiver, //槽函数对象指针
    const char *member, //槽函数字符串,使用SLOT()
    Qt::ConnectionType = Qt::AutoConnection//连接类型,一般默认即可
);

//例如
connect(pushButton, SIGNAL(clicked()), dialog,  SLOT(close()));

Qt4和Qt5都可以使用这种连接方式

2.2.4.2 原型2

static QMetaObject::Connection connect(
    const QObject *sender, //信号发送对象指针
    const QMetaMethod &signal,//信号函数地址
    const QObject *receiver, //槽函数对象指针
    const QMetaMethod &method,//槽函数地址
    Qt::ConnectionType type = Qt::AutoConnection//连接类型,一般默认即可
);

//例如
connect(pushButton, QPushButton::clicked, dialog,  QDialog::close);

Qt5新增这种连接方式,这使得在编译期间就可以进行拼写检查,参数检查,类型检查,并且支持相容参数的兼容性转换。

2.2.5 信号槽示例

新建窗口项目SignalsAndSlotsWidget,类名同为SignalsAndSlotsWidget,基类选择QWidget。

在ui中拖入1个QLineEdit,1个QLable,1个QSlider,如下图


Paste_Image.png

头文件

class SignalsAndSlotsWidget : public QWidget
{
    Q_OBJECT

public:
    explicit SignalsAndSlotsWidget(QWidget *parent = 0);
    ~SignalsAndSlotsWidget();

signals:
    //自定义信号,发出此信号,使得QLabel显示文字
    void sigShowVal(const QString&);

public slots:
    //自定义槽,当LineEdit发出文字改变的信号时,执行这个槽
    void sltLineEditChanged(const QString& text);

private:
    Ui::SignalsAndSlotsWidget *ui;
};

源文件

SignalsAndSlotsWidget::SignalsAndSlotsWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SignalsAndSlotsWidget)
{
    ui->setupUi(this);
    int max = 100;
    int min = 0;
    ui->horizontalSlider->setMaximum(max);//设置最大最小值
    ui->horizontalSlider->setMinimum(min);

    //设置QLineEdit只能输入数字,且为0-100
    QIntValidator* validator = new QIntValidator(min, max, this);
    ui->lineEdit->setValidator(validator);
    connect(ui->lineEdit, &QLineEdit::textChanged, this,  &SignalsAndSlotsWidget::sltLineEditChanged);

    connect(this, SIGNAL(sigShowVal(QString)), ui->label, SLOT(setText(QString)));
}

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

void SignalsAndSlotsWidget::sltLineEditChanged(const QString &text)
{
    int val = text.toInt();
    ui->horizontalSlider->setValue(val);//设置slider当前值
    emit sigShowVal(text);//通知label显示文字
}

运行程序,在输入框中输入0-100,看看有什么变化。

好了,今天就到这里,我们下期再见。

如果你想第一时间看到我的技术分享,就赶快关注吧。

相关文章

  • 2.3信号和槽(上)

    如果面试官问你Qt最明显区别于其它开发框架的特征是什么,那么你的回答一定是信号和槽,为此,小豆君将拿出三节的时间来...

  • 2.3信号和槽(下)

    今天我们终于可以看看神奇的信号槽是怎么实现的了。话不多说,直接上代码。 2.3.1 示例程序 新建控制台应用程序,...

  • 2.3信号和槽(中)

    2.3.1 在ui中编辑信号槽 这一小节我们来看一下如何在ui中编辑信号槽。我们想要在ui中实现点击按钮,能够控制...

  • 信号和槽

    新建项目(application->Qt widgets application)->配置信息(详细信息->bas...

  • WebRTC信号和槽机制

    信号和槽的实现原理大致是这样的 : 信号对象持有连接,连接里记录了槽对象的地址和槽函数(某个成员函数)地址信号对象...

  • QT 练习2:信号和槽

    信号和槽 DEMO

  • Qt学习笔记(四)事件处理机制

    1、信号和槽 Qt中的事件处理机制叫“信号和槽”,signal和slot。模型:对象a中有一个信号signal:X...

  • PyQt信号和槽

    qt里的信号和槽除了可以传递行为外,还可以传递数据,这里以传递DataFrame为例

  • 信号与槽(SIGNAL-SLOT)

    一、系统设置槽-信号 在QtCreator中建立槽信号事件 设置槽事件 设置信号事件 二、自定义槽信号事件 设置对...

  • Qt 信号阻塞 和 断开信号槽

    原文地址: https://blog.csdn.net/u014339020/article/details/79...

网友评论

    本文标题:2.3信号和槽(上)

    本文链接:https://www.haomeiwen.com/subject/rwgjdxtx.html