剪贴板快捷方式/热键绑定与应用程序之外的Qt

时间:2013-08-29 07:42:24

标签: c++ windows qt

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

我正在使用Qt为Windows构建一个与剪贴板相关的应用程序,并且其正常工作的要求之一是能够在我的Qt应用程序之外注册键盘事件,如ctrl + c,ctrl + v。(copy /糊)。我在网上找到的唯一一件事就是为Qt使用外部插件,但整个概念没有得到妥善解释,所以我走到了死胡同。

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

提前致谢!

4 个答案:

答案 0 :(得分:1)

一般来说,绑定剪贴板快捷方式和绑定快捷方式是我发现的两个不同的东西。与剪贴板事件相关,Qt通过其dataChanged()类提供对QClipboard信号的访问。使用它,您可以知道剪贴板数据何时发生了变化,并采取相应的行动,并且无需执行复制/粘贴快捷方式的系统范围绑定。

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:-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();

希望有所帮助。