[英]Clipboard Shortcut/Hotkey binding with Qt outside of application
我曾嘗試使用Google搜索,並在此網站上搜索此搜索,但無濟於事。
我正在使用Qt構建適用於Windows的剪貼板相關應用程序,要使其正常運行,要求之一就是能夠注冊Qt應用程序之外的鍵盤事件,例如ctrl + c,ctrl + v(復制/粘貼)。 。 我在網上發現的唯一一件事是對Qt使用了外部插件,但是整個概念沒有得到正確的解釋,因此我陷入了困境。
有誰知道我該怎么做? 同樣,我想為應用程序注冊將在應用程序本身之外出現的快捷方式。
提前致謝!
綁定剪貼板快捷方式和綁定快捷方式通常是我發現的兩件事。 與剪貼板事件相關,Qt通過其QClipboard類提供對dataChanged()信號的訪問 。 使用此功能,您可以知道剪貼板數據何時更改,並采取相應的行動,並且應該消除對復制/粘貼快捷方式進行系統范圍的綁定的需要。
為了注冊一個全局快捷方式(在這種情況下需要ctrl + v),並且這是我所需要的特定平台,可以在Windows下使用RegisterHotKey函數。 可以從QWidget提供的winId函數獲得作為第一個參數請求的HWND。
為了接受WM_HOTKEY事件,必須在Qt <= 5.0下實現winEvent虛擬保護功能,而在> = 5.0上實現nativeEvent 。
這取決於應用程序在其中運行的桌面環境,並且特定於操作系統。 如果打算在KDE中運行該應用程序,則可以通過在應用程序中部署.desktop文件或將內容添加到/ usr / share / kde4 / apps / khotkeys來輕松注冊全局熱鍵。
在Windows中,最簡單的方法可能是將注冊表項添加到注冊表中以注冊全局熱鍵。 參見MSDN
我認為您只是對剪貼板的工作方式感到困惑。 您無需在應用程序外部注冊與剪貼板相關的熱鍵。 這些由其他應用程序處理。 這些應用程序所做的是與系統范圍的剪貼板進行交互。 您的應用程序需要與同一個剪貼板進行交互,並獲取有關新剪貼板數據可用的通知等。
如果您告訴我們“剪貼板相關”應用程序的含義,則可能會得到更多有用的答案。 它用於出售木制剪貼板嗎? 還是要校准剪貼板彈簧? 還是要管理剪貼板的庫存? 還是在數字剪貼板上運行? 嘆。
這樣可以使您快速啟動並在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();
希望能有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.