Russian Qt Forum
Ноябрь 18, 2024, 09:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Помогите с перехватом клавиш!  (Прочитано 6400 раз)
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" - исход один и тот же.

Всё что нужно это чтоб знающий человек объяснил какой код в какой файл вписать, дальше я разберусь.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #1 : Ноябрь 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;
   }
}
 

И не нужно писать таким здоровым шрифтов Подмигивающий
« Последнее редактирование: Ноябрь 23, 2013, 20:54 от gil9red » Записан

lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #2 : Ноябрь 24, 2013, 00:56 »

Вам помогут:
QAction
QShortcut
QKeySequence

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

Юра.
Ak_Robat
Гость
« Ответ #3 : Ноябрь 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;
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #4 : Ноябрь 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();
 

А лучше всего кидать кода побольше, тут не телепаты сидят Подмигивающий Улыбающийся
Записан

Ak_Robat
Гость
« Ответ #5 : Ноябрь 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();
}
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #6 : Ноябрь 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
Записан

Пока сам не сделаешь...
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.198 секунд. Запросов: 22.