Qt在Mac Cocoa下實現(xiàn)事件過濾的方法
Qt為不同平臺提供了平臺相關(guān)的事件過濾函數(shù), 如X11下為
bool QApplication::x11EventFilter ( XEvent * event ) [virtual] |
一般情況下,開發(fā)者可以通過派生QApplication,然后重寫該函數(shù)獲得程序得到的所有X11事件。 在其他平臺上也有類似的函數(shù)可以重寫。 但筆者在做Mac相關(guān)的程序時在文檔中發(fā)現(xiàn)了這樣一段話
“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編程所知甚少, 一時之間還是覺得有些無所適從, 相信很多朋友跟筆者有同樣的疑慮。 通過在網(wǎng)上查找例子和文檔, 筆者終于搞定了一個小例子, 特在此和廣大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, 相應(yīng)的pro文件也要修改。 pro里還要加上 “LIBS+= -framework AppKit”,因為用到了AppKit提供的NSApplication等API。
個人覺得Mac編程的這些奇怪的條條框框有點太另類,俺是非常不喜歡的。