|
|||||||
C++ и Qt - Глобальные клавиши (hotkeys) в X11, Windows, MacOS
Время создания: 20.03.2016 22:41
Текстовые метки: qt, c++, клавиши, клавиатура
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Принципы написания кода
Запись: xintrea/mytetra_syncro/master/base/0000001079/text.html на raw.github.com
|
|||||||
|
|||||||
Эта тема очень интересная, поэтому именно ей я посвящу этот топик после длительного молчания =). Думаю, за свою практику программисту не может не потребоваться использование глобальных клавиш (hotkeys, shortcuts) в приложении. Благодаря им пользователь может сэкономить своё бессценное время, да и функционал программы повышается. Моей задачей было найти способ регистрирования в системе комбанации клавиш и их дальнейшее транслирование. Задача не очень тяжелая, если выполнять под конретную ОС, а вот сделать кроссплатформенность уже не так легко, нужно учесть некоторые факторы. Давайте возьмемся за X11.
01.#include <QtGui> 02.#include <QX11Info> 03. 04.#include <X11/X.h> 05.#include <X11/Xlib.h> 06.#include <X11/keysym.h> 07. 08.#ifdef KeyPress 09.const int XKeyPress = KeyPress; 10.const int XKeyRelease = KeyRelease; 11.#undef KeyPress 12.#undef KeyRelease 13.#endif 14. 15.class X11ShortCut :QMainWindow 16.{ 17. Q_OBJECT 18. 19.public: 20. X11ShortCut(QWidget *parent) 21. : QMainWindow(parent) 22. { 23. qApp->installEventFilter(this); 24. 25. m_keyCode = XKeysymToKeycode(QX11Info::display(), XK_F11); 26. XGrabKey(QX11Info::display(), m_keyCode, ControlMask|ShiftMask, QX11Info::appRootWindow(), False, GrabModeAsync, GrabModeAsync); 27. XFlush(QX11Info::display()); 28. } 29. 30. ~X11ShortCut() 31. { 32. XUngrabKey(QX11Info::display(), m_keyCode, ControlMask|ShiftMask, QX11Info::appRootWindow()); 33. } 34. 35. bool X11ShortCut::eventFilter(QObject *, QEvent *event) 36. { 37. if(event->type() == QEvent::KeyPress) { 38. QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); 39. int qtKey = keyEvent->key(); 40. if(keyEvent->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier) && qtKey == Qt::Key_F11) { 41. insertPlainText("Ctrl+Shift+F11 pressed!\n"); 42. return false; 43. } 44. } 45. return true; 46. } 47. 48.private: 49. int m_keyCode; 50.}; Здесь и нечего комментировать. m_keyCode = XkeysymToKeycode(QX11Info::display(), XK_F11); Получаем код клавиши F11. Далее регистрируем клавишу в системе с помощью главной функции — XGrabKey Теперь о регистрации «горячих» клавиш в OS Windows. Будем использовать WinApi. Суть та же, мы регистрируем комбинацию с помощью ф-ции WinApi RegisterHotKey() и ожидаем прибытия сообщения WM_HOTKEY (http://msdn.microsoft.com/en-us/library/ms646279(VS.85).aspx) 1.BOOL RegisterHotKey 2.( 3. HWND hWnd, 4. int id, 5. UINT fsModifiers, 6. UINT vk 7.); hWnd — окно, которое должно получать сообщения о активировании глобальной комбинации
1.#DEFINE HOTKEYHIDE 0x000001 2.RegisterHotKey(hwndMain,HOTKEYHIDE,MOD_CONTROL,VK_F12); Как отлавливать сообщения я уже и не помню, это будет Вашим домашним заданием :D. Ещё есть популярная ОС — MacOS, но под неё я ни разу ничего не программировал, поэтому и не раскажу. Читайте далее о кроссплатформенном решении. -----8<----- Так вот, понадобилось мне в одном проекте использовать hotkeys +программа кроссплатформенная, поэтому желательно было найти соответственный фреймворк. Гугл, как всегда, помог мне (хоть и потратил я немало времени). Есть отличное дополнение для Qt, которое называется libQxt (http://libqxt.org). Качаем от туда архив, ставим. Устанавливается это «сокровище» довольно легко: ./configure && make && make install Единственное, я использую QtCreator. В его поставке идет «своя» утилита qmake, поэтому вам нужно её явно указать. Установка немного изменяется: ./configure -qmake-bin /home/%user%/%QtSDk%/qt/bin/qmake Для интеграции в проект нужно в .pro-файл дописать: CONFIG += qxt Документация здесь: http://doc.libqxt.org/. Переходим к делу. В версии 0.5, для использования глобальных клавиш, вам надо создавать объект QxtApplication, а не Qapplication. По словам разработчиков, в версии 0.6 они уберут эту зависимость. Поэтому файл main.cpp изменяется: 01.#include <QtGui/QApplication> 02.#include "mainwindow.h" 03.#include <QxtApplication> 04.int main(int argc, char *argv[]) 05.{ 06. QxtApplication a(argc, argv); 07. MainWindow w; 08. w.show(); 09. return a.exec(); 10.} Далее переходим в класс MainWindow. В .h-файле дописываем: 01.#include <QxtGlobalShortcut> 02. 03.class MainWindow : public QMainWindow 04.{ 05. … 06.private: 07. QString m_shortcutDef; 08. QxtGlobalShortcut m_hotkeyHandle; 09. … 10.private slots: 11. void hotkeyPressed(); 12.} в .cpp-файле: 1.m_shortcutDef = QString("Ctrl+Shift+X"); 2.m_hotkeyHandle.setShortcut( QKeySequence(m_shortcutDef) ); 3.m_hotkeyHandle.setEnabled(true); 4.connect( &m_hotkeyHandle, SIGNAL(activated()), this, SLOT(hotkeyPressed()) ); И, собственно, сам обработчик сообщения: 1.void MainWindow::hotkeyPressed() 2.{ 3. // Achtung 4.} Вот и всё =). Этот код вы можете использовать для X11, Windows, MacOS. Чёто как-то мудрёно у вас, мы использовали следующую комбинацию: #ifndef _HOTKEYS_H #include #define SHORTCUT_SHOW_HELP “F1″ #endif в отдельном *.h файле а в коде так: createShortcut(shortCutHelp, “shortCutHelp”, SHORTCUT_SHOW_HELP, SLOT(on_shortCutHelp())); писали на винде, но должно работать везде. |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|