【问题标题】:How to detect global key sequence press in Qt?如何在 Qt 中检测全局键序列按下?
【发布时间】:2014-06-05 06:15:02
【问题描述】:

我想检测一个按键序列是否被按下,并想在 Qt 中对该事件执行某些任务。目前我可以检测某些小部件的按键,但如何检测全局按键。全局是指即使应用程序被最小化或隐藏,它也应该检测到按键。

我尝试为应用程序创建一个eventFilter,首先像这样重载QObject::eventFilter:

bool GlobalEventFilter::eventFilter(QObject *Object, QEvent *Event)
{
  if (Event->type() == QEvent::KeyPress)
  {
    QKeyEvent *KeyEvent = (QKeyEvent*)Event;

    switch(KeyEvent->key())
    {
      case Qt::Key_F1:
        cout<<"F1 press detected"<<endl;
        return true;
      default:
        break;
    }
  }
  return QObject::eventFilter(Object,Event);
}

然后将该对象安装为我的应用程序的eventFilter:

QApplication a(argc,argv);
a.installEventFilter(new GlobalEventFilter());

我也尝试过这样做:

QCoreApplication::instance()->installEventFilter(new GlobalEventFilter());

在这两种情况下,当我的应用程序窗口打开时,我都能够检测到按键,但在窗口最小化或隐藏时它会失败。如何解决?

【问题讨论】:

  • 这个问答的质量比链接的要好得多。我投票决定重新开放。
  • @Adrian 我同意。我重新打开了这个并关闭了另一个作为这个的副本。

标签: c++ windows qt


【解决方案1】:

查看QKeyEvent的文档:

当按键被按下或释放时,按键事件被发送到具有键盘输入焦点的小部件。

这意味着,如果你想使用QKeyEvent,你需要有键盘焦点。过滤这些事件也不会在概念上改变这一点。我不确定你从哪里得到过滤的想法。

您可能想研究替代解决方案,例如它是如何在 kwin 中实现的,等等。一般来说,请小心这个用例。它可以在最终用户没有注意到的情况下做一些奇怪的事情。

你可以看看这个类:

QxtGlobalShortcut Class Reference

你可以这样写:

main.cpp

#include <QxtGlobalShortcut>

#include <QApplication>
#include <QMainWindow>
#include <QDebug>

class MyGlobalShortcutHandler : public QObject
{
    Q_OBJECT
public:
    explicit MyGlobalShortcutHandler(QObject *parent = 0)
        : QObject(parent)
    {
        m_globalShortcut.setShortcut(QKeySequence("Ctrl+Shift+X"));
        m_globalShortcut.setEnabled(true);

        connect(&m_globalShortcut, SIGNAL(activated()), SLOT(handleGlobalShortcut()));
    }

public slots:
    void handleGlobalShortcut()
    {
        qDebug() << "Global shortcut handled";
    }

private:
    QxtGlobalShortcut m_globalShortcut;
};

#include "main.moc"

int main(int argc, char **argv)
{
    QApplication application(argc, argv);
    QMainWindow mainWindow;
    MyGlobalShortcutHandler myGlobalShortcut();
    mainWindow.show();
    return application.exec();
}

main.pro

TEMPLATE = app
TARGET = main
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += qxt
QXT = core gui
SOURCES += main.cpp

构建并运行

qmake-qt4 && make && ./main

这段代码至少应该适用于 Qt 4。它为我打印出调试语句。您可以轻松地验证这一点。

要获取 libqxt 库,请访问以下链接:

http://dev.libqxt.org/libqxt/wiki/Home

【讨论】:

  • 我见过很多应用程序这样做。它不是那么困难的任务。其实在使用WinApi之前我也做过。
  • 我不管是QKeyEvent还是别的什么。如果可能的话,我只想要一种 Qt 方式。如果没有,我将不得不使用 WinApi 来实现。
  • 我无法下载 Qxt 库。我不断收到此错误:已超出此资源的速率限制。
  • @user221458:尝试dev.libqxt.org/libqxt/get/v0.6.2.tar.gz 并使用总指挥官插件左右解压缩它。如果你不能做到这一点,我可以为你重新包装。
  • 我可以将 Qxt 用于闭源商业应用程序吗?我读了它的许可证,我很困惑。我不能在 LGPL 许可下使用它吗?
【解决方案2】:

这个特性在 Qt 中没有实现。您可以使用Qxt。 Qxt 是 Qt 的扩展库,提供了一套跨平台的实用程序类来添加 Qt 中不可用的功能。它具有全局快捷键(热键),即使应用程序已最小化,它也会检测按键。

编译并链接你的应用到Qxt之后,你可以包含QxtGlobalShortcut:

#include <QxtGlobalShortcut>

示例用法:

QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));

【讨论】:

  • 看起来很有希望,但我不想为了实现它而在我的项目中添加额外的库。
  • 我无法从他们的网站下载 Qxt:我收到此错误:当我尝试打开此链接时已超出此资源的速率限制:dev.libqxt.org/libqxt/get/v0.6.2.zip 是否有任何镜像?
  • 有时我得到同样的错误,有时我可以得到它。尝试刷新下载链接可能会得到它。
  • 感谢您的回答我知道这个问题已经有很长时间了,但是如果我想让鼠标点击我应该写的内容,您可以帮忙吗?并提前致谢
猜你喜欢
  • 1970-01-01
  • 2020-05-02
  • 2022-01-18
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
  • 2022-11-17
相关资源
最近更新 更多