1

I've tried googling, and searching on this site about this but to no avail.

I am building a Clipboard related application for Windows using Qt, and one of the requirements for it to work right is to be able to register for keyboard events outside my Qt application, like ctrl + c, ctrl + v. (copy/paste). The only thing that I have found online is using an external plugin for Qt but the entire concept was not explained properly, so I hit a dead end.

Does anyone have an idea how I can do this? Again, I want to register shortcuts to my application that will occur outside the application itself.

Thanks in advance!

4 Answers4

1

Binding clipboard shortcuts and binding shortcuts in general are as I have discovered, two different things. Related to Clipboard events, Qt provides access to a dataChanged() signal through its QClipboard class. Using that, you are able to know when the clipboard data has changed, and act accordingly, and should eliminate the need to perform a system-wide binding of the Copy/Paste shortcuts.

In order to register a global shortcut (in this case the need for ctrl + v), and this is platform specific like in my needs, one can use the RegisterHotKey function under Windows. The HWND requested as the first parameter can be obtained from the winId function that is provided by QWidget.

In order to accept the WM_HOTKEY event, one would have to implement the winEvent virtual protected function under Qt <= 5.0, and nativeEvent on >= 5.0.

0

This depends on the Desktopenvironment the application runs in and it is OS-specific. If you intend to run the application within KDE you can register global hotkeys easyly by deploying a .desktop File with your Application or by adding things to /usr/share/kde4/apps/khotkeys .

Within Windows, the easiest way would probably be adding a registry key to the registry in order to register a global Hotkey. See MSDN

SeDav
  • 761
  • 7
  • 19
0

I think you're just confused about how the clipboard works. You never need to register clipboard-related hotkeys outside of your application. Those are handled by other applications. What those applications do is interact with the system-wide clipboard. Your application needs to interact with the same clipboard and get notifications about new clipboard data being available etc.

You might get more helpful answers if you tell us what you mean by a "clipboard related" application. Is it used to sell wooden clipboards? Or to calibrate clipboard springs? Or to manage inventory of clipboards? Or does it run on a digital clipboard? Sigh.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
-1

This should get you up and running in Windows+Qt and HotKeys pretty quickly.

I haven't tried the Qt eXTension library with QxtGlobalShortcut, but it sounds like it may be a more elegant complete solution for more platforms. (like in @TimMeyer's comment to your question)

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

I wrote up this function to listen for a single system wide hotkey in 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 file

#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);
}

Usage in your 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();

and when your program is closing use

 m_hot_key_thread->stop();

Hope that helps.

Community
  • 1
  • 1
phyatt
  • 18,472
  • 5
  • 61
  • 80
  • Would you consider adding a few comments to explain what everything means and/or what it does, and perhaps how to use it instead of just using it? This will help people customize it to their own purposes. – cat40 Mar 15 '17 at 16:46
  • See the two lines that have the comment `// modify this line`? Put in a specific virtual keyboard code there and any modifiers you want. Then you program will receive signals from Windows events to Qt Slots. – phyatt Mar 15 '17 at 16:53