1

我试过谷歌搜索,并在这个网站上搜索这个但无济于事。

我正在使用 Qt 为 Windows 构建一个与剪贴板相关的应用程序,它正常工作的要求之一是能够在我的 Qt 应用程序之外注册键盘事件,例如 ctrl + c、ctrl + v。(复制/粘贴) . 我在网上发现的唯一一件事是使用 Qt 的外部插件,但整个概念没有得到正确解释,所以我走到了死胡同。

有谁知道我该怎么做?同样,我想为我的应用程序注册快捷方式,这些快捷方式将出现在应用程序本身之外。

提前致谢!

4

4 回答 4

1

正如我所发现的,绑定剪贴板快捷方式和绑定快捷方式通常是两种不同的东西。与剪贴板事件相关,Qt 通过其QClipboard类提供对dataChanged()信号的访问。使用它,您可以知道剪贴板数据何时更改,并采取相应措施,并且应该消除对复制/粘贴快捷方式执行系统范围绑定的需要。

为了注册一个全局快捷方式(在这种情况下需要 ctrl + v),这是平台特定的,就像我的需要一样,可以在 Windows 下使用RegisterHotKey函数。作为第一个参数请求的 HWND 可以从 QWidget 提供的winId函数中获取。

为了接受 WM_HOTKEY 事件,必须在 Qt <= 5.0 和nativeEvent on >= 5.0下实现winEvent虚拟保护功能。

于 2013-08-29T19:30:59.550 回答
0

这取决于应用程序运行的桌面环境,并且是特定于操作系统的。如果您打算在 KDE 中运行应用程序,您可以通过在应用程序中部署 .desktop文件或向 /usr/share/kde4/apps/khotkeys 添加内容来轻松注册全局热键。

在 Windows 中,最简单的方法可能是将注册表项添加到注册表中以注册全局热键。见MSDN

于 2013-08-29T07:53:31.510 回答
0

我认为您只是对剪贴板的工作方式感到困惑。您永远不需要在应用程序之外注册与剪贴板相关的热键。这些由其他应用程序处理。这些应用程序所做的是与系统范围的剪贴板交互。您的应用程序需要与同一个剪贴板进行交互,并获得有关新剪贴板数据可用等的通知。

如果您告诉我们“剪贴板相关”应用程序的含义,您可能会得到更多有用的答案。它是用来卖木制剪贴板的吗?或者校准剪贴板弹簧?或者管理剪贴板的库存?还是在数字剪贴板上运行?叹。

于 2013-08-29T18:43:46.303 回答
-1

这应该可以让您在 Windows+Qt 和 HotKeys 中快速启动并运行。

我还没有尝试过使用 QxtGlobalShortcut 的 Qt eXTension 库但听起来它可能是针对更多平台的更优雅的完整解决方案。(就像@TimMeyer 对您的问题的评论一样)

https://stackoverflow.com/a/3154652/808151

我编写了这个函数来监听 Windows 中的单个系统范围的热键。

#ifndef HOTKEYTHREAD_H
#define HOTKEYTHREAD_H

#include <QThread>

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

class HotKeyThread : public QThread
{
    Q_OBJECT

public:
    HotKeyThread(QObject *parent);
    ~HotKeyThread();
signals:
    void hot_key_event(int);
public slots:
    void run();
    void stop();
private:
    volatile bool m_stopped;
    DWORD m_thread_id;
};

#endif // HOTKEYTHREAD_H

.cpp 文件

#include "hotkeythread.h"

#include <QDebug>
#include <process.h> 

#define WM_END_THREAD (WM_USER+2)

HotKeyThread::HotKeyThread(QObject *parent)
    : QThread(parent)
{
    this->m_thread_id = 0;
}

HotKeyThread::~HotKeyThread()
{

}

void HotKeyThread::stop()
{
    if(this->m_thread_id != 0)
        ::PostThreadMessage(this->m_thread_id, WM_END_THREAD, 0, 0);
}

//
void HotKeyThread::run()
{
    // store a thread id so we can exit later
    m_thread_id = ::GetCurrentThreadId();

    qDebug() << "ThreadIDs" << QString::number(m_thread_id, 16) << QString::number((int) this->currentThreadId(), 16);

    // register an atom, and a hotkey
    BOOL retVal;
    int counter = 0;
    int magic_num = 1128;
    ATOM id = ::GlobalAddAtom(MAKEINTATOM(magic_num + counter++));

    // http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
    int modifier = 0x0;// modify this line
    int key = VK_NUMPAD0;// modify this line
    if(QSysInfo::windowsVersion() > QSysInfo::WV_VISTA)
    {
        retVal = ::RegisterHotKey(NULL, id, modifier | MOD_NOREPEAT, key);
    }
    else
    {
        // No repeat is only supported in 7 and later
        retVal = ::RegisterHotKey(NULL, id, modifier, key);
    }

    if(retVal)
    {
        qDebug() << "Successfully added a HotKey!";
    }
    else
    {
        qDebug() << "Failed to add a hotkey!";
        return;
    }

    // wait on hotkeys
    MSG msg = {0};
    while (0 < ::GetMessage(&msg, NULL, 0, 0))
    {
        if(msg.message == WM_HOTKEY)
        {
            bool control = LOWORD(msg.lParam) & MOD_CONTROL;
            bool shift = LOWORD(msg.lParam) & MOD_SHIFT;
            bool alt = LOWORD(msg.lParam) & MOD_ALT;
            bool win = LOWORD(msg.lParam) & MOD_WIN;
            qDebug() << "HotKey!" << (control ? "Ctrl +": "") 
                << (alt ? "Alt +": "")
                << (shift ? "Shift +":"") 
                << (win ? "Win +":"") << QString::number(HIWORD(msg.lParam),16);
            // TODO Notify MainWindow of the event
            emit hot_key_event(msg.lParam);
        }
        else if(msg.message == WM_END_THREAD)
        {
            // exit
            break;
        }
    }

    // Clean up Hotkey
    ::UnregisterHotKey(NULL, id);
    ::GlobalDeleteAtom(id);
}

在您的 GUI 中使用

 // Start HotKey Thread!
 m_hot_key_thread = new HotKeyThread(this);
 QObject::connect(m_hot_key_thread, SIGNAL(hot_key_event(int)), 
             this, SLOT(handle_hot_key_event(int)), Qt::QueuedConnection);
 m_hot_key_thread->start();

当你的程序关闭使用

 m_hot_key_thread->stop();

希望有帮助。

于 2013-08-29T21:24:21.483 回答