Qt 全局热键的详细解析

Qt 全局热键 QxtGlobalShortcut 分析与使用举例,与你分享,如果你需要全局热键,那么本文将会为你解决。
首先: 使用 RegisterHotKey和 UnregisterHotKey 注册和反注册热键
其次: 在事件全局过滤器 winEventFilter 中相应热键,但是涉及其他平台的,中文资料中提到的似乎不多。
libqxt
其实Qt第三方的库 libqxt 中已经给出了一个比较好的跨平台的解决方案,这就是 QxtGlobalShortcut。
所以,只要你使用这个第三方库就可以了。
可是,你会不会想,我仅仅为了使用这个类,而引入这个 libqxt 第三方库是不是有点大题小做?我能不能将其剥离出来单独使用?
QxtGlobalShortcut
恩,用google搜索一下,就可以知道,网上很多人都做过这个工作了。你会发现很多人将剥离出的 QxtGlobalShortcut 作为项目的 3rdparty 部分。
那么我们接下来就看看这个 QxtGlobalShortcut :
用法
已经简单到不能再简单了,是不?
1. QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(QKeySequence("Ctrl+Shift+F12"), w);
connect(shortcut, SIGNAL(activated()), w, SLOT(myslot()));注意:如果你对其内部实现不感兴趣,只关心如何使用,那么这个小例子可能就是你需要的全部了 :
http://code.google.com/p/h-qt-exercise/downloads/detail?name=shortcut.zip&can=2&q=
源码文件
1. gxtglobal.h
libqxt 一个全局文件
1. qxtglobalshortcut.h
我们最关心的接口文件
1. qxtglobalshortcut_.h
私有头文件
1. gxtglobalshortcut.cpp
类的实现(平台无关部分)
1. gxtglobalshortcut_win.cpp
类的实现(win)
1. gxtglobalshortcut_x11.cpp
类的实现(x11)
1. gxtglobalshortcut_mac.cpp
类的实现(mac)
热键的注册过程
我们通过构造函数,或者setShortcut 成员设置一个热键时:
首先将这个 QKeySequence 分解成两部分 Qt::Key 和 Qt::KeyboardModifiers
(即:下面的 key 和 mods)
然后,key 和 mods 分别转换成平台相关(native)的码值,并调用平台相关的函数进行注册
最后,将key与mods的native码值构成的QPair作为QHash的键,将该shortcut的指针作为值保存起来。
1. bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
2. {
3. ...
4. key = ...
5. mods = ...
6. const quint32 nativeKey = nativeKeycode(key);
7. const quint32 nativeMods = nativeModifiers(mods);
8. const bool res = registerShortcut(nativeKey, nativeMods);
9. shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
反注册的过程与此类似。
热键激活
首先给 QAbstractEventDispatcher 安装事件过滤器
1. QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);注意,这儿不是给 QApplication 安装的。Manual中是这样告诉我们的
2. bool QCoreApplication::winEventFilter ( MSG * msg, long * result ) [virtual]
3. To handle system wide messages, such as messages from a registered hot key,
4. you need to install an event filter on the event dispatcher,
5. which is returned from QAbstractEventDispatcher::instance().然后我们在过滤器中分别进行处理,比如windows下
6. bool QxtGlobalShortcutPrivate::eventFilter(void* message)
7. {
8. MSG* msg = static_cast<MSG*>(message);
9. if (msg->message == WM_HOTKEY){
10. const quint32 keycode = HIWORD(msg->lParam);
11. const quint32 modifiers = LOWORD(msg->lParam);
12. activateShortcut(keycode, modifiers);
13. }
14. return false;
15. }
16. 或 x11 下:
17. bool QxtGlobalShortcutPrivate::eventFilter(void* message)
18. {
19. XEvent* event = static_cast<XEvent*>(message);
20. if (event->type == KeyPress){
21. XKeyEvent* key = (XKeyEvent*) event;
22. activateShortcut(key->keycode, key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
23. }
24. return false;
25. }
其中activateShortcut是平台无关的:
1. void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)
2. {
3. QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods));
4. if (shortcut && shortcut->isEnabled())
5. emit shortcut->activated();
6. }
记得前面注册热键是保存东西到一个QHash么?它是在这儿起作用的,当一个热键到来时,我们从该QHash查找有没有相应的QxtGlobalShortcut存在,存在且启用的话,则发射信号。
如何使用
为了便于使用,我们可以在这个文件的同级目录中添加一个 qxtglobalshortcut.pri 的文件:
1. INCLUDEPATH += $$PWD
2. DEPENDPATH += $$PWD
3.
4. HEADERS += $$PWD/qxtglobal.h \
5. $$PWD/qxtglobalshortcut.h \
6. $$PWD/qxtglobalshortcut_p.h
7. SOURCES += $$PWD/qxtglobalshortcut.cpp
8. win32{
9. SOURCES += $$PWD/qxtglobalshortcut_win.cpp
10. LIBS += -luser32
11. }
12. unix:SOURCES += $$PWD/qxtglobalshortcut_x11.cpp
13. mac:SOURCES += $$PWD/qxtglobalshortcut_mac.cpp
这样一来,当我们使用时,只需要在我们的pro文件内多加一行:
include(yourpath/qxtglobalshortcut.pri)即可
一个具体的小例子:http://code.google.com/p/h-qt-exercise/downloads/detail?name=shortcut.zip&can=2&q=
小结:Qt 全局热键 QxtGlobalShortcut 分析与使用举例的内容为大家介绍完了,希望你帮你解决问题。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt 中,可以通过 `qInstallMessageHandler()` 函数设置全局的异常处理函数,用于捕获 Qt 中的异常。这个函数接受一个指向消息处理函数的指针,该函数将在出现异常时被调用。在消息处理函数中,可以将异常信息输出到控制台或者写入日志文件等操作。下面是一个简单的例子: ```cpp void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QString txt; switch (type) { case QtDebugMsg: txt = QString("Debug: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(context.line).arg(context.function); break; case QtWarningMsg: txt = QString("Warning: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(context.line).arg(context.function); break; case QtCriticalMsg: txt = QString("Critical: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(context.line).arg(context.function); break; case QtFatalMsg: txt = QString("Fatal: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(context.line).arg(context.function); abort(); } // 输出到控制台 QTextStream(stdout) << txt; // 或者写入日志文件 QFile file("log.txt"); if (file.open(QIODevice::WriteOnly | QIODevice::Append)) { QTextStream stream(&file); stream << txt; file.close(); } } int main(int argc, char *argv[]) { QApplication app(argc, argv); // 设置全局异常处理函数 qInstallMessageHandler(myMessageOutput); // ... return app.exec(); } ``` 在这个例子中,定义了一个名为 `myMessageOutput()` 的函数作为消息处理函数,并通过 `qInstallMessageHandler()` 函数设置为全局异常处理函数。在 `myMessageOutput()` 函数中,根据异常类型不同输出不同的日志信息,并将其输出到控制台或者写入日志文件中。最后在 `main()` 函数中调用 `qInstallMessageHandler()` 函数将全局异常处理函数设置为 `myMessageOutput()` 函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值