Различные статьи по Qt и c++

QShortcut в Qt: горячие клавиши в приложении

обновлено 590 просмотров

Введение

Горячие клавиши делают приложение удобнее: опытные пользователи выполняют частые действия без мыши. В Qt для этого есть класс QShortcut. Он связывает сочетание клавиш с сигналом, который можно подключить к любому слоту или лямбде. Сочетание может включать модификаторы Shift, Ctrl, Alt и Meta. В статье разберём, как создать горячую клавишу через QShortcut, как ограничить её действие окном или виджетом и чем QShortcut отличается от QAction.

Подключение QShortcut

Для использования класса подключите заголовочный файл:

#include <QShortcut>

В Qt 6 класс находится в модуле QtGui, в Qt 5 — в QtWidgets. Для обычного приложения с виджетами дополнительно ничего подключать не нужно.

Пример: две горячие клавиши в главном окне

Создадим в главном окне две горячие клавиши: F7 и Ctrl+V. При нажатии каждой будет появляться сообщение.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QShortcut>
#include <QMessageBox>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void slotF7();
    void slotCtrlV();

private:
    Ui::MainWindow *ui;
    QShortcut *keyF7;       // F7
    QShortcut *keyCtrlV;    // Ctrl + V
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    keyF7 = new QShortcut(QKeySequence(Qt::Key_F7), this);
    connect(keyF7, &QShortcut::activated, this, &MainWindow::slotF7);

    keyCtrlV = new QShortcut(QKeySequence("Ctrl+V"), this);
    connect(keyCtrlV, &QShortcut::activated, this, &MainWindow::slotCtrlV);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::slotF7()
{
    QMessageBox::information(this, "keyF7", "slotF7", QMessageBox::Ok);
}

void MainWindow::slotCtrlV()
{
    QMessageBox::information(this, "keyCtrlV", "slotCtrlV", QMessageBox::Ok);
}

Родителем QShortcut передаётся главное окно, поэтому объекты удалятся вместе с ним. При нажатии F7 или Ctrl+V появится диалоговое окно:

QShortcut: сообщение после нажатия F7
Сообщение F7
QShortcut: сообщение после нажатия Ctrl+V
Сообщение Ctrl+V

Способы задать сочетание клавиш

Сочетание описывается классом QKeySequence. Его можно задать несколькими способами:

// Строкой — самый наглядный вариант
QKeySequence("Ctrl+Shift+S");

// Кодами клавиш и модификаторов
QKeySequence(Qt::CTRL | Qt::Key_S);

// Стандартным действием — сочетание зависит от платформы
QKeySequence(QKeySequence::Save);

Стандартные сочетания (Copy, Paste, Save, Undo, Find и другие) учитывают привычки пользователей разных систем. Например, в macOS «Сохранить» — это Cmd+S, а не Ctrl+S. В старом коде можно встретить запись Qt::CTRL + Qt::Key_V. В Qt 6 оператор + для этого устарел, используйте |.

Короткая запись с лямбдой

Начиная с Qt 5.15, обработчик можно передать прямо в конструктор. Отдельный слот не нужен:

new QShortcut(QKeySequence("Ctrl+Q"), this, [this]() {
    close();
});

Где действует горячая клавиша

По умолчанию QShortcut срабатывает, только когда активно окно, которому принадлежит родительский виджет. Это поведение меняется методом setContext():

  • Qt::WindowShortcut — внутри активного окна (по умолчанию);
  • Qt::WidgetShortcut — только когда фокус на родительском виджете;
  • Qt::WidgetWithChildrenShortcut — когда фокус на виджете или его дочерних элементах;
  • Qt::ApplicationShortcut — в любом окне приложения.
auto *shortcut = new QShortcut(QKeySequence(Qt::Key_Delete), ui->tableView);
shortcut->setContext(Qt::WidgetShortcut);
connect(shortcut, &QShortcut::activated, this, &MainWindow::deleteSelectedRows);

В этом примере клавиша Delete удаляет строки, только когда фокус находится в таблице, и не мешает удалению текста в полях ввода.

Полезные методы и сигналы

  • setEnabled(false) — временно отключить горячую клавишу;
  • setAutoRepeat(false) — не срабатывать повторно при удержании клавиши;
  • сигнал activatedAmbiguously() — приходит, если одно сочетание назначено нескольким объектам в одном контексте.

Помните о конфликтах. Если поле ввода в фокусе само обрабатывает Ctrl+V для вставки текста, оно получит сочетание раньше. Поэтому не назначайте свои действия на стандартные системные сочетания без необходимости.

QShortcut или QAction

Если действие есть в меню или на панели инструментов, удобнее использовать QAction с методом setShortcut(). Тогда сочетание автоматически отобразится в меню рядом с пунктом. QShortcut подходит для действий, у которых нет видимого элемента интерфейса.

Заключение

QShortcut — простой способ добавить горячие клавиши в приложение на Qt. Создайте объект с нужным QKeySequence, подключите сигнал activated() к слоту или лямбде и при необходимости ограничьте контекст. Полный список кодов клавиш и модификаторов находится в перечислениях Qt::Key и Qt::KeyboardModifier, объявленных в заголовке qnamespace.h.