我试过谷歌搜索,并在这个网站上搜索这个但无济于事。
我正在使用Qt为Windows构建一个与剪贴板相关的应用程序,并且其正常工作的要求之一是能够在我的Qt应用程序之外注册键盘事件,如ctrl + c,ctrl + v。(copy /糊)。我在网上找到的唯一一件事就是为Qt使用外部插件,但整个概念没有得到妥善解释,所以我走到了死胡同。
有谁知道我该怎么做?同样,我想在应用程序本身之外注册我的应用程序的快捷方式。
提前致谢!
答案 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();
希望有所帮助。