连接的信号打错了。
QObject::connect(spinBox, SIGNAL(valueChanged(int)),
slider, SLOT(setValue(int)));
QObject::connect(slider, SIGNAL(valueChanged(int)),
spinBox, SLOT(setValue(int)));
1、回调函数
一个回调可以认为是一个指向函数的指针。当满足某种条件时,消息处理函数将调用该回调函数进行事件的处理。类似于win32的消息循环机制,当某一事件产生,由系统转化成消息并进入消息循环队列时,应用程序将根据消息的类型来决定对某个回调函数的调用。类似于下面的伪代码:
//消息循环队列
while(getMessageFromSystem(&msg))//一直从系统获取消息(事件)
{
switch(msg.type())
{
case MOUSE_EVENT:
handleMouseEvent();
break;
case KEYBOARD_EVENT:
handleKeyBoardEvent();
break;
....
}
}
采用这种方式会存在一些缺陷:首先他们不是类型安全的,我们不能保证消息处理函数会采用正确的参数来调用回调函数;其次回调函数对消息处理函数有很强的依赖性,因为消息处理函数必须清楚如何对回调函数进行调用。
2、信号和槽
在qt中,采用了信号和槽作为回调函数的替代方式。当某个事件发生时,某个信号将被发送(emit)出去,而相应的槽将接受该信号进行消息处理。比如窗口中有一个QPushButton m_button,我要通过点击该按钮来实现窗口的关闭。由于按钮被点击之后将发出 clicked() 信号,而窗口的关闭由槽函数 close() 来实现。我们只需要关联信号 clicked() 和槽 close(),代码如下:
connect(&m_button,SIGNAL(clicked()),this,SLOT(close()));
这样我们在点击对象m_button时,将自动关闭该窗口。
由上面可见,信号和槽的连接是通过QObject::connect()函数来实现的。我们可以关联任意的信号和槽,可以将一个信号关联到多个槽,也可以将多个信号关联到一个槽,也可以把一个信号关联到另一个信号,总之有很高的灵活性。信号和槽是相对独立的,它们可以存在于各自的模块之中,要使它们之间建立消息传递的机制,只需要简单的调用connect()
信号和槽避免了上述回调所带来的缺陷,首先信号和槽都会进行严格的参数类型检查,这样也就保证了类型安全;其次,信号和槽是松耦合的,信号发送者不需要关心谁来接受这个信号,它只负责把信号发送出去。而qt的信号和槽机制又保证了在合适的时候调用信号所关联的槽函数(会存在一个信号队列对信号进行管理),同时槽函数也可以作为一个普通的成员函数进行调用。
当然这只是信号和槽的一些最基本的特性,关于qt的信号和槽实现机制可以查看qt assistant中的Meta-Object System,关于connect()函数的详细介绍可以查看QObject::connect()以及QObject::disconnect()函数的详细介绍。
其他相关的文档:qt assistant中的 Signals and Slots 一节
注意:要使用信号和槽机制,需要继承自QObject,并在类的private区域加上Q_OBJECT宏
个人观点,难免有不对之处,望指正