×
Namespaces

Variants
Actions

Archived:如何在Qt程序中拦截所有Symbian事件

From Nokia Developer Wiki
Jump to: navigation, search

Archived.png存档: 这篇文章是存档,因为考虑到今天它与第三方开发者建立商业解决方案不相关。

Qt Quick should be used for all UI development on mobile devices. The approach described in this article (based on QWidget) is deprecated.

Article Metadata

兼容于
平台:
Symbian

文章
zhouhl 在 03 Sep 2010 创建
最后由 hamishwillee 在 11 Oct 2012 编辑

Contents

引言

有时候在用Qt写Symbian应用的时候,我们会希望直接从Symbian操作系统获得事件,因为经过Qt翻译之后的事件有时候满足不了我们的需要。

截获所有Symbian事件,会使我们的程序拥有更高的自主权,也给了我们更多自由发挥的空间。熟悉Symbian的同学们更会觉得方便。

从Qt 4.6 开始Qt就开始支持截获所有Symbian事件了,下面我们就具体看一下如何实施。

继承QApplication

通常Qt GUI程序都是从构造一个QApplication对象开始的,但是我们如果想截获所有Symbian事件是不能简单的这么做的。首先我们需要设计一个自己的QApplication类。也就是我们写一个继承自QApplication的类。 例如:

#ifndef FNAPPLICATION_H
#define FNAPPLICATION_H
 
#include <QApplication>
#include <QSymbianEvent>
 
class FNApplication : public QApplication
{
Q_OBJECT
public:
explicit FNApplication(int argc, char *argv[]);
 
virtual bool symbianEventFilter ( const QSymbianEvent * event );
 
signals:
void layoutChange();
void focusGained();
void focusLost();
 
public slots:
 
};
 
#endif // FNAPPLICATION_H

并且实现QApplication的虚方法:

bool QApplication::symbianEventFilter ( const QSymbianEvent * event )   [virtual]

其中的event参数可以是任何类型的Symbian事件,这都是由QSymbianEvent进行封装的。在实现此函数时,如果我们想拦截此事件就return true,否则的话return false。此函数的默认实现是return false,即不做任何处理,交由Qt底层处理。

拦截ResourceChangeEvent

我们可以使用这个函数获取ResourceChangeEvent中具体的事件类型:

int QSymbianEvent::resourceChangeType () const

使用方法举例。
例如拦截横竖屏切换的ResourceChangeEvent如下:

    if(event->type() == QSymbianEvent::ResourceChangeEvent)
{
if(event->resourceChangeType() == KEikDynamicLayoutVariantSwitch)
{
emit layoutChange(); //我们这里通过发送一个信号来进行我们自己的处理
return true; //如果我们想让系统继续处理,就可以写return false;
}
else
return false;
}

拦截WindowServerEvent

我们可以使用这个函数直接获取WindowServerEvent中所包含的TWsEvent(Symbian的Window server event):

const TWsEvent * QSymbianEvent::windowServerEvent () const

使用方法举例。
例如拦截window group获取失去焦点的Window server事件的代码如下:

const TWsEvent * wsevent = event->windowServerEvent();
if( !wsevent ) {
return false;
}
 
switch( wsevent->Type() )
{
case EEventFocusGained: {
emit focusGained();
return true;
break;
}
case EEventFocusLost: {
emit focusLost();
return true;
break;
}
default:
return false;
break;
}

拦截CommandEvent

int QSymbianEvent::command () const

我们可以通过此函数获得even中所包含的command,使用方法与以上类似。

拦截后对所拦截事件进行处理

有很多种方式。我们这里采用signal slot的方式进行处理,在上述例子代码中我们拦截到事件后都发送了一个signal。对signal的处理我们可以放在任何地方,比如我们就交由主窗口的一个slot进行处理。那么我们只需要在main函数中进行连接一下就可以了。例如:

int main(int argc, char *argv[])
{
#if defined(Q_WS_S60)
FNApplication a(argc, argv);
#else
QApplication a(argc, argv);
#endif
 
MainWindow w;
 
#if defined(Q_WS_S60)
QObject::connect(&a, SIGNAL(layoutChange()), &w, SLOT(handleLayoutChange())); //交由MianWindow的slot处理
QObject::connect(&a, SIGNAL(focusGained()), &w, SLOT(handlefocusGained()));
QObject::connect(&a, SIGNAL(focusLost()), &w, SLOT(handlefocusLost()));
w.showMaximized();
#else
w.show();
#endif
return a.exec();
}

加入必要的头文件和库

例如我们如果使用TWsEvent就需要加上w32std.h,如果我们使用ResourceChangeEvent就需要加上akndef.h,具体需要什么请大家参考Symbian文档。

示例代码

#include "fnapplication.h"
#include <w32std.h>
#include <akndef.h>
 
FNApplication::FNApplication(int argc, char *argv[]) :
QApplication(argc, argv)
{
}
 
bool FNApplication::symbianEventFilter ( const QSymbianEvent * event )
{
switch( event->Type() )
{
case QSymbianEvent::ResourceChangeEvent:{
if(event->resourceChangeType() == KAknFullOrPartialForegroundGained)
{
emit focusGained();
return true;
}
else
return false;
break;
}
case QSymbianEvent::WindowServerEvent:{
const TWsEvent * wsevent = event->windowServerEvent();
switch( wsevent->Type() )
{
case EEventFocusGained: {
emit focusGained();
return true;
break;
}
case EEventFocusLost: {
emit focusLost();
return true;
break;
}
default:
return false;
break;
}
break;
}
default:
return false;
break;
}
}

相关链接

This page was last modified on 11 October 2012, at 04:15.
268 page views in the last 30 days.
×