|
本帖最后由 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 将会给出警告。
|
|