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();
- }
上面这段代码将接收到的键盘按下的事件打印到console上。除了语法是奇怪的Objective C的语法之外, 没有什么难点, 相信大家都是看得懂的。 还有一点值得提醒的地方, 就是这段代码保存的文件必须以.mm为后缀名, 也就是我们通常写的main.cpp要改成main.mm, 相应的pro文件也要修改。 pro里还要加上 “LIBS+= -framework AppKit”,因为用到了AppKit提供的NSApplication等API。
个人觉得Mac编程的这些奇怪的条条框框有点太另类,俺是非常不喜欢的。