Signals and Slots 翻译

Signals and Slots
Signals and slots are used for communication between objects. The signals and slots mechanism is a central feature of Qt and probably the part that differs most from the features provided by other frameworks.
信号和槽被用作Qt 对象间通信的方式。这种信号/ 的机制既是Qt 的核心特性,又是区别于其它GUI 框架所能提供的此类功能的一个方面。
 
Introduction
In GUI programming, when we change one widget, we often want another widget to be notified. More generally, we want objects of any kind to be able to communicate with one another. For example, if a user clicks a Close button, we probably want the window's close() function to be called.
GUI 编程中,当我们想要改变某个窗体部件时,我们总是想让其它部件获悉这一变动。更普遍的是,我们想要各种类型的对象间能够通信。比如,假设用户点击了关闭按钮,这很有可能是想调用窗体的关闭功能。
 
Older toolkits achieve this kind of communication using callbacks. A callback is a pointer to a function, so if you want a processing function to notify you about some event you pass a pointer to another function (the callback) to the processing function. The processing function then calls the callback when appropriate. Callbacks have two fundamental flaws: Firstly, they are not type-safe. We can never be certain that the processing function will call the callback with the correct arguments. Secondly, the callback is strongly coupled to the processing function since the processing function must know which callback to call.
老式的开发包会通过回调函数来实现这样的通信。所谓的回调函数是使用了一个函数指针,当你想要传递其它函数(回调函数,不能显式调用)的指针到正在执行的函数(调用者)的时候,这个执行着的函数能够及时通知你这个事件的发生,并在适当的时候就会去调用回调函数。回调函数有两个本质的缺点,第一,它们并不基于类型安全,你永远都不能确定调用者是否通过正确的函数签名来调用回调函数;第二,回调函数与调用者是紧耦合的,因为调用者必须知道应该在什么时候调用哪个回调函数。
 
Signals and Slots
In Qt, we have an alternative to the callback technique: We use signals and slots. A signal is emitted when a particular event occurs. Qt's widgets have many predefined signals, but we can always subclass widgets to add our own signals to them. A slot is a function that is called in reponse to a particular signal. Qt's widgets have many pre-defined slots, but it is common practice to subclass widgets and add your own slots so that you can handle the signals that you are interested in.
Qt 使用了信号/ 的机制来代替回调函数。当一个具体的事件发生时,信号会被发送出去。Qt 的窗体部件拥有众多定义好的信号,当然,我们也可以创建窗体部件的子类来增加自己需要的信号。而槽,则是一个具体的信号的反馈。Qt 的窗体部件同样的拥有众多定义好的槽,但是更为普遍的是,创建子类来增加新的槽来控制你想要的信号。
 
The signals and slots mechanism is type safe: The signature of a signal must match the signature of the receiving slot. (In fact a slot may have a shorter signature than the signal it receives because it can ignore extra arguments.) Since the signatures are compatible, the compiler can help us detect type mismatches. Signals and slots are loosely coupled: A class which emits a signal neither knows nor cares which slots receive the signal. Qt's signals and slots mechanism ensures that if you connect a signal to a slot, the slot will be called with the signal's parameters at the right time. Signals and slots can take any number of arguments of any type. They are completely type safe.
信号/ 机制是类型安全的,信号的签名必须与接受该信号的槽的签名匹配。(实际上,槽有可能拥有比它接收的信号更短的签名,因为槽能够忽略具体的函数形参。)因为签名匹配的,所以编译器能帮助我们检测没有匹配的类型。另外,信号和槽是松耦合的,发送信号的类不会知道也不关心接收该信号的槽。信号/ 的机制确保了在你使用信号与槽在进行通信的时候,槽能准确地通过该信号的参数进行调用。
 
All classes that inherit from QObject or one of its subclasses (e.g., QWidget) can contain signals and slots. Signals are emitted by objects when they change their state in a way that may be interesting to other objects. This is all the object does to communicate. It does not know or care whether anything is receiving the signals it emits. This is true information encapsulation, and ensures that the object can be used as a software component.
Qt 中,所有的类都继承于包信号和槽的QObject ,或者它的子类(比如,QWidget )。当对象要改变它们状态的时候(通常有可能通过吸引其它的对象的方式),信号会被发送出去。这就是所有对象进行通信的方式。这样的形式并不知道也不会去关心它们发送出去的信号是否会被接收。这样的一种信息封装确保了对象能够作为软件组件来使用。
 
Slots can be used for receiving signals, but they are also normal member functions. Just as an object does not know if anything receives its signals, a slot does not know if it has any signals connected to it. This ensures that truly independent components can be created with Qt.
槽被用来接收信号,但除此之外,它们仍然可以被作为普通的成员函数使用。槽不会知道是否有信号与它联系起来,就像对象不知道它发出信号被接受一样。这就确保了Qt 创建一个个独立的组件。
 
You can connect as many signals as you want to a single slot, and a signal can be connected to as many slots as you need. It is even possible to connect a signal directly to another signal. (This will emit the second signal immediately whenever the first is emitted.)
你可以把你想要的所有的信号与某个槽进行通信,也可以让一个信号与你需要的所有的槽进行通信。你也可以做到将一个信号与另一个信号直接联系起来(这样就能做到当第一个信号发送出去的时候,第二个信号紧接着被发送出去)。
 
Together, signals and slots make up a powerful component programming mechanism.
就这样,信号与槽构成了强大的组件编程机制。
 
A Small Example
A minimal C++ class declaration might read:
如下是一个最小化的C++ 类的声明:
class  Counter
{
public:
Counter() 
{ m_value = 0; }

int value() const return m_value; }
void setValue(int value);

private:
int m_value;
}
;
 
A small QObject-based class might read:
如下是一个小型的基于QObject 的类声明:
#include  < QObject >

class  Counter :  public  QObject
{
Q_OBJECT

public:
Counter() 
{ m_value = 0; }

int value() const return m_value; }

public slots:
void setValue(int value);

signals:
void valueChanged(int newValue);

private:
int m_value;
}
;
 
The QObject-based version has the same internal state, and provides public methods to access the state, but in addition it has support for component programming using signals and slots. This class can tell the outside world that its state has changed by emitting a signal, valueChanged(), and it has a slot which other objects can send signals to.
基于QObject 的类拥有如上相同的内部状态,并提供访问这些状态的公有方法,但是,它还另外提供支持组件编程的信号和槽。这样的类能够对外宣布它通过发送信号改变自己的状态,比如发送valueChanged() 信号,同时它也拥有槽,来接收其它对象发送的信号。
 
All classes that contain signals or slots must mention Q_OBJECT at the top of their declaration. They must also derive (directly or indirectly) from QObject.
所有包含信号和槽的类都必须在声明的开头标示“Q_OBJECT” ,还必须从QObject 继承(无论是直接的还是间接的)。
 
Slots are implemented by the application programmer. Here is a possible implementation of the Counter::setValue() slot:
槽需要程序员自己来实现。如下是Counter::setValue() 槽的一个实现:
void  Counter::setValue( int  value)
{
if (value != m_value) {
m_value 
= value;
emit valueChanged(value);
}

}

The emit line emits the signal valueChanged() from the object, with the new value as argument.
“emit” 这一行表示,从这个对象中将作为函数形参的新value 通过valueChanged() 信号发送出去。
 
In the following code snippet, we create two Counter objects and connect the first object's valueChanged() signal to the second object's setValue() slot using QObject::connect():
如下的代码片断中,我们创建了两个Counter 对象,同时通过QObject::connect() 将第一个对象的valueChanged() 信号与第二个对象的setValue() 槽联系起来。
Counter a, b;
QObject::connect(
& a, SIGNAL(valueChanged( int )),
& b, SLOT(setValue( int )));

a.setValue(
12 );  //  a.value() == 12, b.value() == 12
b.setValue( 48 );  //  a.value() == 12, b.value() == 48
 
Calling a.setValue(12) makes a emit a valueChanged(12) signal, which b will receive in its setValue() slot, i.e. b.setValue(12) is called. Then b emits the same valueChanged() signal, but since no slot has been connected to b's valueChanged() signal, the signal is ignored.
调用a.setValue(12) ,会发送一个valueChanged(12) 的信号,b 对象会通过它的setValue() 槽来接收该信号,这样也就调用了b.setValue(12) 。与此同时,b 也会发送同样的valueChanged() 的信号,但是这个时候并没有槽与b 对象的valueChanged() 信号联系,所以这个信号也就被丢弃了。
 
Note that the setValue() function sets the value and emits the signal only if value != m_value. This prevents infinite looping in the case of cyclic connections (e.g., if b.valueChanged() were connected to a.setValue()).
在这里要注意,setValue() 函数当且仅当value != m_value 的情况下,才会设置value 的值并且发送信号。这样就阻止了在信号轮转时发生的无限循环的逻辑错误(比如在b.valueChanged() a.setValue() 连接的情况下)。
 
A signal is emitted for every connection you make; if you duplicate a connection, two signals will be emitted. You can always break a connection using QObject::disconnect().
信号会通过你设置的每一个连接进行发送,也就意味着当你复制一个连接的时候,同时就会有两个信号被发送。你也可以通过QObject::disconnect() 来终止连接。
 
This example illustrates that objects can work together without needing to know any information about each other. To enable this, the objects only need to be connected together, and this can be achieved with some simple QObject::connect() function calls, or with uic's automatic connections feature.
这个例子说明了对象间能够协同工作而无需知道对方的任何信息。为了使用这样的机制,仅需要通过调用简单的QObject::connect() 函数把对象连接起来,或者通过uic 的自动连接特性即可。
 

你可能感兴趣的:(Signals and Slots 翻译)