×
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.
205 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×