原文网址:http://www.dazzle.plus.com/linux/QtCreator/part04.htm
第4部份:增强状态栏
信号和槽
使用Qt信号和槽机制,我们增强状态栏让它可以显示用户在中央显示区域点击时的鼠标位置。信号和槽机制让相互之间没有依赖关系的对象之间通信变得很容易。这个概念就是对象发送信号包括事件信息,被别的对象接收,使用槽这种特殊的函数。信号和槽系统很适合图形用户界面设计方式。
Qt图形视图框架用于创建的中央显示部件提供了许多有用的功能,其中包括让我们检测到用户点击时的鼠标位置。我们将增强我们的Scene类检测到用户点击它会发送一个信号,我们也会增强MainWindow类用槽检测到这种信号,然后把接收到的信息显示在状态栏上。
增强类Scene
为了检测到用户点击的位置我们将实现mousePressEvent方法让它接收QGraphicsSceneMouseEvent事件。要发送信号我们必须添加一个宏Q_OBJECT和一个信号方法。我们的信号方法叫作“message”,带一个文本字符串参数。这个宏Q_OBJECT是放在类定义的私有区域,是用来启用Qt的元对象功能比如动态属性,信号和槽。
因为我们不需要把类QGraphicsSceneMouseEvent的所有定义放在这个头文件里,我们只添加一个类的前置定义。
class QGraphicsSceneMouseEvent;
在类定义中添加宏Q_OBJECT。
Q_OBJECT
添加信号方法和mousePressEvent方法的定义。
signals:
void message( QString ); // 文本消息信号
protected:
void mousePressEvent( QGraphicsSceneMouseEvent* ); // 接收鼠标按下事件
引入QGraphicsSceneMouseEvent头文件。
#include <QGraphicsSceneMouseEvent>
添加mousePressEvent方法的实现。这里我们使用QGraphicsSceneMouseEvent提供给我们的信息,检测用户是否按下鼠标左键和鼠标的位置。
/********************************** mousePressEvent **********************************/
void Scene::mousePressEvent( QGraphicsSceneMouseEvent* event )
{
// 判断用户是否按下鼠标左键
if ( event->button() != Qt::LeftButton ) return;
// 发送信息信号
qreal x = event->scenePos().x();
qreal y = event->scenePos().y();
emit message( QString("Clicked at %1,%2").arg(x).arg(y) );
}
我们并不需要提供信号方法的实现,Qt元对象编译器就会为我们实现(见后面)。
增强MainWindow
要接收信号我们必须添加宏Q_OBJECT和一个槽方法我们叫作“showMessage”。
在类的定义里添加宏Q_OBJECT。
Q_OBJECT
添加槽方法的定义。
public slots:
void showMessage( QString ); // 在状态栏上显示消息
在类mainwindow构造函数里我们需要把槽和信号连接起来。
//把场景里的信号message和槽showMessage连接起来
connect( m_scene, SIGNAL(message(QString)), this, SLOT(showMessage(QString)) );
添加槽方法的实现把信号的文本消息显示在状态栏上。
/************************************ showMessage ************************************/
void MainWindow::showMessage( QString msg )
{
// 在主窗口状态栏上显示消息
statusBar()->showMessage( msg );
}
编译和运行
如果现在我们来编译代码,将会在看到编译错误信息“undefined reference to‘vtable for MainWindow'”,因为我们使用了像信号和槽这种Qt元对象功能,QtCreator也需要Qt元对象编译(moc)。我们需要重新运行qmake告诉QtCreator元对象编译。最简单的方法是在“构建”菜单选择“执行 qmake”。
现在当我们试图运行项目时,新代码将被成功编译。运行应用程序并点击中央白色区域看看状态栏的变化。