Russian Qt Forum

Программирование => С/C++ => Тема начата: Ak_Robat от Ноябрь 23, 2013, 20:15



Название: Помогите с перехватом клавиш!
Отправлено: Ak_Robat от Ноябрь 23, 2013, 20:15
Вопрос собственно такой: как при нажатии некоторых клавиш выполнять определённые процедуры.
Немного поясню. Если активно окно приложения, то нажатие клавиш должно прехватываться (не зависимо от виджета в фокусе).


Я перерыл немало форумов, но это мне совсем не помогло (не из-за отсутствия полезной инфы, скорее из-за моей неопытности в qt creator, знаю пока мало библиотек и много незнакомых методов для меня).

Вот то, что я нашёл в учебнике:
Код:
void MyWidget::keyPressEvent(QKeyEvent* pe) {

    switch (pe->key()) {
    case QT::Key_Backspace:
        //события;
        break;

    default:
        break;
    }
}

Компилятор ругается на MyWidget (вроде вполне логично) и я понятия не имею где его нужно объявить.
Пробовал объявить его в хедере, пробовал подключать "QKeyEvent", "QEvent", "QtGui" - исход один и тот же.

Всё что нужно это чтоб знающий человек объяснил какой код в какой файл вписать, дальше я разберусь.


Название: Re: Помогите с перехватом клавиш!
Отправлено: gil9red от Ноябрь 23, 2013, 20:43
Делаем так:
  • Наследуемся от QWidget или от любого его наследника (например QDialog, QMainWindow, QFrame и т.п.)
  • Переопределяем функции нужных событий, у нас это событие зажатия клавиши keyPressEvent и в нем пишем свою логику :)
  • ...
  • Profit!!!

Код:
h:
Код
C++ (Qt)
#include <QWidget>
#include <QKeyEvent>
#include <QDebug>
 
class MyWidget: public QWidget
{
Q_OBJECT
 
public:
   MyWidget( QWidget * parent = 0 ); // конструктор
 
protected:
  void keyPressEvent( QKeyEvent * event ); // функция события
};
 

cpp:
Код
C++ (Qt)
/// PUBLIC
MyWidget::MyWidget( QWidget * parent)
     : QWidget( parent )
{
  // выполняем какой-нибудь код
}
 
/// PROTECTION
void MyWidget::keyPressEvent( QKeyEvent * event )
{
   switch ( event->key() )
   {
   case Qt::Key_Backspace:
       qDebug() << "Press key backspace";
       break;
 
   case Qt::Key_Return:
       qDebug() << "Press key enter";
       break;
 
   default:
       break;
   }
}
 

И не нужно писать таким здоровым шрифтов ;)


Название: Re: Помогите с перехватом клавиш!
Отправлено: lit-uriy от Ноябрь 24, 2013, 00:56
Вам помогут:
QAction
QShortcut
QKeySequence

А использовать обработчики событий имеет смысл только в случае невозможности достичь нужного результата выше указанными классами


Название: Re: Помогите с перехватом клавиш!
Отправлено: Ak_Robat от Ноябрь 24, 2013, 16:29
Большое Спасибо, gil9red, за помощь, всё компилируется.
Но мне не удалось затестить корректность работы, т.к. возникла днугая (совершенно неожиданная) проблема.

Фактически при нажатии клавиши мне нужно вызвать событие ON_CLICKED уже существующей кнопки.
Оказалось реализовть это в qt не так-то просто. Как обратиться к форме и её виджетам из глобальной области? Помогите ещё раз пожалуйста.
Необходимо сделать что-то вроде:
Код:
case Qt::Key_Backspace:
    MainWindow.on_butBacks_clicked();

p.s. в заголовке изменил строки:
Код:
private:
    Ui::MainWindow *ui;
на следующие:
Код:
public:
    Ui::MainWindow *ui;


Название: Re: Помогите с перехватом клавиш!
Отправлено: gil9red от Ноябрь 24, 2013, 23:43
Чтобы программно кликнуть на кнопку, можно у кнопки вызвать метод click():

// Если предположить что objectName вашей кнопки butBacks, то:
Код
C++ (Qt)
case Qt::Key_Backspace:
       ui->butBacks->click();    
 

// Если кнопка должна при нажатии выполнить слот on_butBacks_clicked() и этот слот вам нужно вызвать, то:
Код
C++ (Qt)
case Qt::Key_Backspace:
       on_butBacks_clicked();
 

А лучше всего кидать кода побольше, тут не телепаты сидят ;) :)


Название: Re: Помогите с перехватом клавиш!
Отправлено: Ak_Robat от Ноябрь 25, 2013, 17:26
Цитировать
// Если предположить что objectName вашей кнопки butBacks, то:
Код:
case Qt::Key_Backspace:
        on_butBacks_clicked();
     

Да, это именно то, что нужно, но суть в том, что я вызываю функцию on_butBacks_clicked() из глобальной области cpp (а именно из метода keyPressEvent моего собственного класса MyWidget), поэтому эта функция не распознаётся.

Код:
void MyWidget::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {

        case Qt::Key_Backspace:
            on_butBacks_clicked(); //ПРОБЛЕМА
            break;

        default:
            break;
    }
}

Вопрос в том как корректно обратиться к форме и её виджетам из вне? (т.к. ни указатель ui, ни w [объект класса MainWindow, описанный в main.cpp] тоже почему-то не опознаны там)
Например в том же C++ Builder это бы выглядело так:

Код:
case Qt::Key_Backspace:
    Form1->butBacks->on_click(); //или что-то похожее, уже не помню
    break;

А как реализовать то же самое в Qt?

ps. main.cpp:
Код:
#include "mainwindow.h"
#include <QApplication>
#include <QEvent>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}


Название: Re: Помогите с перехватом клавиш!
Отправлено: ViTech от Ноябрь 25, 2013, 17:55
Да, это именно то, что нужно, но суть в том, что я вызываю функцию on_butBacks_clicked() из глобальной области cpp (а именно из метода keyPressEvent моего собственного класса MyWidget), поэтому эта функция не распознаётся.
Не нужно вызывать on_butBacks_clicked() из глобальной области cpp. И обработчик нажатия на кнопку откуда либо вообще :). Нужно сделать слот, который выполняет необходимые действия, а к нему подключать сигналы от кнопок, действий, сочетаний клавиш.

Вопрос в том как корректно обратиться к форме и её виджетам из вне? (т.к. ни указатель ui, ни w [объект класса MainWindow, описанный в main.cpp] тоже почему-то не опознаны там)
Например в том же C++ Builder это бы выглядело так:
...

К виджетам формы, по-хорошему, тоже обращаться не нужно. То, что находится на форме - ее внутреннее дело. Взаимодействовать с внешними объектами она должна по другому.

Изучайте простые примеры на Qt. Например, что быстро нагуглилось:
http://open-life.org/blog/QT/295.html
http://code-live.ru/post/getting-started-qt