设为首页收藏本站
查看: 12066|回复: 0

Qt的信号和槽机制

[复制链接]

34

主题

9

回帖

363

积分

中级会员

积分
363
conway 发表于 2015-7-20 15:55:55 | 显示全部楼层 |阅读模式
本帖最后由 conway 于 2015-7-20 15:59 编辑

先来看看下面一段代码:
[mw_shl_code=applescript,true]#include <QApplication>
#include <QHBoxLayout>
#include <QSlider>
#include <QLCDNumber>
int main(int argc, char *argv[])

{
    QApplication app(argc, argv);
    QWidget *window = new QWidget;
    window->setWindowTitle("Enter a number");
    QLCDNumber * lcd = new QLCDNumber;
    QSlider *slider = new QSlider(Qt::Horizontal);
    slider->setRange(0, 99);

    QObject::connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));

    slider->setValue(35);

    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(lcd);
    layout->addWidget(slider);
    window->setLayout(layout);
    window->show();
    return app.exec();
}[/mw_shl_code]
该程序要求用户通过 slider 输入一个0~99的数字,并利用 lcd 显示。程序中使用了三个控件:
QLCDNumber,QSlider 和 QWidget。QWidget 是这个程序的主窗口。QLCDNumber 和 QSlider 被放在 QWidget 中,所以它们是 QWidget 的 children。反过来,也可以称 QWidget 是 QLCDNumber 和 QSlider 的 parent。QWidget 没有 parent,因为它是程序的顶层窗口。在QWidget 及其子类的构造函数中,都有一个 QWidget*参数,用来指定它们的父控。
其中用户的交互行为是通过connect函数实现,利用Qt的信号和槽机制来管理。

信号和槽是 Qt 编程的一个重要部分,这个机制可以在对象之间彼此并不了解的情况下 将它们的行为联系起来。在上面的例程中,已经连接了信号和槽,发送了信号,触发槽函数 的响应,下面将更深入介绍这个机制。

槽和普通的 c++成员函数很像。它们可以是虚函数(virtual),也可被重载(overload), 可以是公有的(public),保护的(protective),也可是私有的(private),它们可以象任何 c++ 成员函数一样被调用,可以传递任何类型的参数。不同在于一个槽函数能和一个信号相连接, 只要信号发出了,这个槽函数就会自动被调用。信号和槽函数间的连接通过 connect 实现。 connect 函数语法如下:

[mw_shl_code=applescript,true]connect(sender, SIGNAL(signal), receiver, SLOT(slot));[/mw_shl_code]

sender 和 receiver 是 QObject 对象(QObject 是所有 Qt 对象的基类)指针,signal 和 slot
是不带参数的函数原型。SIGNALE()和 SLOT()宏的作用是把他们转换成字符串。

在前面的例子中,已经连接了信号和槽,而在实际使用中还需要考虑如下一些规则:

1)一个信号可以连接到多个槽:

[mw_shl_code=applescript,true]connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int)));
connect(slider, SIGNAL(valueChanged(int)),this, SLOT(updateStatusBarIndicator(int)));[/mw_shl_code]

当信号发出后,槽函数都会被调用,但是调用的顺序是随机的,不确定的。

2)多个信号可以连接到一个槽:

[mw_shl_code=applescript,true]connect(lcd, SIGNAL(overflow()), this, SLOT(handleMathError()));
connect(calculator, SIGNAL(divisionByZero()),this, SLOT(handleMathError()));[/mw_shl_code]
任何一个信号发出,槽函数都会执行。

3)一个信号可以和另一个信号相连:

[mw_shl_code=applescript,true]connect(lineEdit, SIGNAL(textChanged(const QString &)), this, SIGNAL(updateRecord(const QString &)));[/mw_shl_code]

第一个信号发出后,第二个信号也同时发送。除此之外,信号与信号连接上和信号和槽 连接相同。

4)连接可以被删除:

[mw_shl_code=applescript,true]disconnect(lcd, SIGNAL(overflow()),this, SLOT(handleMathError()));[/mw_shl_code]

这个函数很少使用,一个对象删除后,Qt 自动删除这个对象的所有连接。

信号和槽函数必须有着相同的参数类型,这样信号和槽函数才能成功连接:

[mw_shl_code=applescript,true]connect(ftp, SIGNAL(rawCommandReply(int, QString &)),this, SLOT(processReply(int, QString &)));[/mw_shl_code]

如果信号里的参数个数多于槽函数的参数,多余的参数被忽略:

[mw_shl_code=applescript,true]connect(ftp, SIGNAL(rawCommandReply(int, const QString &)),this, SLOT(checkErrorCode(int)));[/mw_shl_code]

如果参数类型不匹配,或者信号和槽不存在,在 debug 状态时,Qt 会在运行期间给出 警告。如果信号和槽连接时包含了参数的名字,Qt 将会给出警告。








回复

使用道具 举报

您需要登录后才可以回帖 登录

本版积分规则

Archiver|手机版|小黑屋|米尔科技论坛   

GMT+8, 2024-11-25 18:05 , Processed in 0.047802 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表