需求
当前应用程序激活时,无论在哪个窗口,都要响应设置的快捷键
解决方案
首先想到的是全局热键,可以使用的第三方库有QHoteky、qxtglobalshortcut5,
我采用了QHotkey,原因是对CMake支持比较好,qxtglobalshortcut5还需要自己写CMake。
但是在实际使用过程中,发现这两个lib注册全局快捷键必须都放在
QApplication::exec()
之前。
这是因为 QApplication::exec() 负责启动 Qt 的事件循环,处理用户界面交互的事件等,而 QHotkey 类内部是使用QAbstractNativeEventFilter - nativeEventFilter
的方式来检测全局快捷键事件并触发 activated 信号。因此,必须确保 QHotkey 对象在 QApplication::exec() 函数被调用之前已经创建,以便在事件循环开始时能够正确地注册全局快捷键监听器。如果将 QHotkey 对象的创建在 QApplication::exec() 函数调用之后,那么 Qt 事件循环已经开始运行,QHotkey 还没有机会来注册监听器,此时您的全局快捷键可能无法正常工作。
QShortcut
实际发现全局热键的方案其实有点小题大作,认真研究了下QShortcut
在 Qt 中,QShortcut 类用于为一个或多个 QWidget 对象注册一组快捷键。QShortcut 的构造函数有两个参数:
QShortcut::QShortcut(const QKeySequence &key, QWidget *parent = nullptr)
其中,第一个参数 key 是一个 QKeySequence 对象,用于指定要注册的快捷键组合。第二个参数 parent 是一个 QWidget 指针,用于指定当前快捷键的父对象。
QWidget 可以是任何继承自 QWidget 的对象,例如 QMainWindow、QDialog、QPushButton 等等。当 QWidget 处于激活状态时,注册的快捷键组合就可以被响应。
需要注意的是,如果在创建 QShortcut 对象时忘记指定 parent 参数,则该快捷键只会在程序进程中起作用,而不能在当前界面中被响应。因此,在使用 QShortcut 时,通常应该将 parent 参数设置为当前需要响应快捷键的 QWidget 对象。
如果你在 QMainWindow 上注册了快捷键,那么所有子窗口中也会响应该快捷键。这是由于 QMainWindow 会将快捷键事件分发给它的所有子 QWidget 对象,而不仅限于 QMainWindow 本身。
如果你希望只有当前活动的子窗口响应快捷键,可以使用 QAction 类来代替 QShortcut 类进行注册。QAction 是一个专门用于处理动作的类,它提供了与 QShortcut 类似的快捷键注册接口,同时也支持菜单、工具条等界面元素的创建和管理。
QWidget* win = nullptr; QShortcut* shortcurt = new QShortcut(QKeySequence(Qt::Key_Space), win); QObject::connect(shortcurt, &QShortcut::activated, this, []() { qDebug() << "22"; });