Qt为不同平台提供了平台相关的事件过滤函数, 如X11下为
bool QApplication::x11EventFilter ( XEvent * event ) [virtual] |
一般情况下,开发者可以通过派生QApplication,然后重写该函数获得程序得到的所有X11事件。 在其他平台上也有类似的函数可以重写。 但笔者在做Mac相关的程序时在文档中发现了这样一段话
“bool QApplication::macEventFilter ( EventHandlerCallRef caller, EventRef event ) [virtual] Warning: This virtual function is only implemented under Mac OS X when against Carbon.” |
这说明在用Cocoa时, 标准的Qt方法没有办法截获程序的事件。 文档后面还描述了在Cocoa下该如何做才能得到事件:
“Cocoa uses a different event system which means this function is NOT CALLED when building Qt against Cocoa. If you want similar functionality subclass NSApplication and reimplement the sendEvent: message to handle all the NSEvents. You also will need to to instantiate your custom NSApplication before creating a QApplication. SeeApple’s NSApplication Reference for more information.” |
这段话说来算是很详细具体了, 但由于笔者对Mac编程所知甚少, 一时之间还是觉得有些无所适从, 相信很多朋友跟笔者有同样的疑虑。 通过在网上查找例子和文档, 笔者终于搞定了一个小例子, 特在此和广大qter分享, 希望对大家有所帮助。 闲话少说, 上代码:
#include
#include
#include "mainwin.h"
@interface KeyLoggerApplication : NSApplication
{
}
@end
@implementation KeyLoggerApplication
- (BOOL)sendEvent:(NSEvent *)anEvent {
NSEventType type = [anEvent type];
bool handled = NO;
if (type == NSKeyUp)
{
switch( [anEvent keyCode] )
{
default:
NSLog(@"Keypressed: %d, **%@**", [anEvent keyCode], [anEvent characters]);
break;
}
}
//handle only the keys i need then let the other go through the regular channels
//this stops the annoying beep
if( !handled )
[super sendEvent:anEvent];
}
@end
int main(int argc, char* argv[])
{
[KeyLoggerApplication sharedApplication];
QApplication a(argc, argv);
MainWin mw;
mw.show();
return a.exec();
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
上面这段代码将接收到的键盘按下的事件打印到console上。除了语法是奇怪的Objective C的语法之外, 没有什么难点, 相信大家都是看得懂的。 还有一点值得提醒的地方, 就是这段代码保存的文件必须以.mm为后缀名, 也就是我们通常写的main.cpp要改成main.mm, 相应的pro文件也要修改。 pro里还要加上 “LIBS+= -framework AppKit”,因为用到了AppKit提供的NSApplication等API。
个人觉得Mac编程的这些奇怪的条条框框有点太另类,俺是非常不喜欢的。