Linux 版 (精华区)

发信人: tcpip (高级草包), 信区: Linux
标  题: Qt Documentation --------Signals, Slots and the M
发信站: 哈工大紫丁香 (2000年06月11日12:59:45 星期天), 转信

Qt Documentation --------Signals, Slots and the Meta Object Compiler(未完)  

Signals, Slots and the Meta Object Compiler


翻译:lyp 

QT程序使用signal和slot来进行对象之间的通信. signal和slot是QT的核心机制, 
也是QT与其他工具的主要区别. 

在大多数图形界面工具包中, 控件都为他们操作的每一个动作使用一个回调函数, 
这些回调函数是函数指针.
在QT中, 使用signal和slot避免了使用函数指针可能 带来的问题. 

signal和slot可以带有任意类型的参数, 而且要求类型匹配, 因此避免了回调函 
数可能造成的core dump! 

所有继承了QObject或它的子类(例如: QWidget)的类均可具有signal和slot. 当
对象的状态发生改变并可能对外界其他对象有用时即可发送signal. 所有对象都 
是这样进行通信的.
它并不需要知道任何有关接收方的信息. 这对于信息封装是 完全正确的, 
保证了对象可以作为软件组件来使用.

slot可以用来接收signal, 但它们也可作为常规的成员函数来使用. slot并不知道 
它是否与某一signal连接.
而且对象也不知道具体的通信机制, 因此也可以作为软 件组件来使用. 

每个slot上可以连接任意数目的signal, 每个signal可以连接到任意数目的slot上. 

综上所述, signal和slot提供了一种强有力的组件编程机制. 

一个例子:

一个最小的C++类大概可以这样来写: 

class Foo
{
public:
Foo();
int value() const { return val; }
void setValue( int );
private:
int val;
};

一个相似的QT类可以这样写: 

class Foo : public QObject
{
Q_OBJECT
public:
Foo();
int value() const { return val; }
public slots:
void setValue( int );
signals:
void valueChanged( int );
private:
int val;
};

这两个类具有相同的内部变量和外部接口函数, 但是基于QT的类还提供了支持组件编 
程的signal和slot:
当它的值改变时, 它可以通过signal: valueChanged()s告诉外界. 
而且也提供了一个slot,
使其他对象可以发送signal给它. 

所有包含signals/slots的类在它们的定义中必须包含Q_OBJECT语句 

slot是由应用程序的编写者实现的. 例如可以这样实现:Foo::setValue(): 

void Foo::setValue( int v )
{
if ( v != val ) {
val = v;
emit valueChanged(v);
}
}

行emit valueChanged(v) 发送一个valueChanged() signal给其他对象. 你可以看到, 
发送signal时使用emit
signal(arguments). 

下面说明如何连接两个对象: 

Foo a, b;
connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));
b.setValue( 11 ); //b的值为11.
a.setValue( 79 );
b.value(); // 这时b的值为79, 为什么呢?

当调用a.setValue(79)时对象a将发送valueChanged(79) 这样一个signal, 
而b将接受这一signal,
即调用setValue(79), 因此b的值发生改变, 变为79, 同时b也将发送一个 
valueChanged(79)这 样一个signal,
但没有对象接受, 因为没有对象连接, 因此这个sgianl就被丢弃了. 

注意: 只有在值发生改变时才发送signal(v!=val), 这避免了当循环连接时
(例如:b.valueChanged(int)再连接到a.setValue(int))造成死循环. 

这个例子演示了即使对象之间互相不清楚对方也可以协同工作, 只要事先建立了 
它们之间的连接关系. 

编译器的预处理程序将改变或删除signals,slots 和emit等关键字, 
因此编译器不会在编译时发生错误. 

对于包含signals和slots的类应该使用moc处理一下, 生成的
C++源文件应该和该类的源代码一起编译和连接到应用程序中. 

 
 -- 
"这一千多年没写诗了?" 
"写了, 不过只写了两句." "千年得两句, 一定是万古丽句了. 念来听听."
"好吧, 我现丑了" 太白星清了清嗓子, 浑厚的男中音在天庭响起:大海啊, 都是水;
骏马啊, 四条腿;

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: tcpip.hit.edu.cn]
--
※ 修改:·tcpip 於 06月11日12:59:58 修改本文·[FROM: tcpip.hit.edu.cn]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.223毫秒