crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> как перехватить нажатие на клавишу <Enter>?
breeve
  опции профиля:
сообщение 27.12.2009, 21:38
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 188
Регистрация: 26.12.2009
Пользователь №: 1336

Спасибо сказали: 9 раз(а)




Репутация:   1  


Вот у меня есть код, необходимо его переделать таким образом чтобы считывал не комбинацию клавиш, а одну клавишу <Enter>.
    qatmp = new QAction(this);
    qatmp->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
    connect(qatmp,SIGNAL(triggered()), this,SLOT(mySlot()));
    addAction(qatmp);


Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 27.12.2009, 23:02
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


есть два способа:
1) Унаследоватся от интерисуемого класса и переопределить в нём событие обработки клавиш
2) Установить на интерисуемый объект фильтр событий.

Я думаю второй способ будет удобнее, см. описание к методу:
void QObject::installEventFilter ( QObject * filterObj )
там есть пример. в качестве объекта обрабатывающего событие можно использовать виджет-окно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
breeve
  опции профиля:
сообщение 28.12.2009, 10:59
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 188
Регистрация: 26.12.2009
Пользователь №: 1336

Спасибо сказали: 9 раз(а)




Репутация:   1  


Цитата(Litkevich Yuriy @ 27.12.2009, 23:02) *
есть два способа:
1) Унаследоватся от интерисуемого класса и переопределить в нём событие обработки клавиш
2) Установить на интерисуемый объект фильтр событий.

Я думаю второй способ будет удобнее, см. описание к методу:
void QObject::installEventFilter ( QObject * filterObj )
там есть пример. в качестве объекта обрабатывающего событие можно использовать виджет-окно.


Облазил не одну страницу документации.. и что только не пробовал не работает..
У меня есть предположение что ентер является стандартной комбинацией на перенос каретки на новую строку(QKeySequence::InsertParagraphSeparator).
Может ли этот факт как-то влиять?
Насчет того примера, вот он:
Раскрывающийся текст
class KeyPressEater : public QObject
{
     Q_OBJECT
     ...

protected:
     bool eventFilter(QObject *obj, QEvent *event);
};

bool KeyPressEater::eventFilter(QObject *obj, QEvent *event)
{
     if (event->type() == QEvent::KeyPress) {
         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
         qDebug("Ate key press %d", keyEvent->key());
         return true;
     } else {
         // standard event processing
         return QObject::eventFilter(obj, event);
     }
}
//-------------------------------------------------------------------------

KeyPressEater *keyPressEater = new KeyPressEater(this);
QPushButton *pushButton = new QPushButton(this);
QListView *listView = new QListView(this);

pushButton->installEventFilter(keyPressEater);
listView->installEventFilter(keyPressEater);


Вообщем я этот код вообще не понимаю.. :unsure:
Единственное что я понял, так это то что делает функция: ты нажимаешь любую кнопку и он выводит ее код в консоль..
А вот остальное я не понимаю надо создать второй класс или можно вставить в существующий..
Еще "в качестве объекта обрабатывающего событие можно использовать виджет-окно" -- это я наверное не понял..

Сообщение отредактировал breeve - 28.12.2009, 11:06
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.12.2009, 12:34
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(breeve @ 28.12.2009, 13:59) *
Еще "в качестве объекта обрабатывающего событие можно использовать виджет-окно" -- это я наверное не понял..
это тот класс который у тебя описывает окно приложения (в твоём примере он назывался Button). Тогда получается, что у тебя должна добавиться функция: bool Button::eventFilter(QObject *obj, QEvent *event). в которой ты будешь вызывать mySlot() (вместо печати в консоль)

В самом классе Button, после создания объекта, у которого нужно перехватить событие (у тебя это один из QTextEdit'ов) устанавливаешь фильтр событий:
textEdit->installEventFilter(this);
Здесь написано this, т.к. этот объект и будет являться фильтром (перехватчиком) событий.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
breeve
  опции профиля:
сообщение 28.12.2009, 13:21
Сообщение #5


Участник
**

Группа: Участник
Сообщений: 188
Регистрация: 26.12.2009
Пользователь №: 1336

Спасибо сказали: 9 раз(а)




Репутация:   1  


Видимо я нуб, каких свет не видывал))
Сделал как Litkevich Yuriy, сказал и вот что вышло..
вот это QEvent::KeyPress в условии это же нажатие любой кнопки.. И получается что не нажму он мне отвечает)).. А как сделать именно кнопку Ентер? Куда вставить ее код?
Я попробовал сделать так:
Раскрывающийся текст
 if (event->type() == QEvent::KeyPress) {
         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
         if(keyEvent->key() == Qt::Key_Return)
         mySlot();

только теперь у меня ентер работает а все остальное нет.. т.е пытаюсь что то ввести в текстЕдит он игнорит!

Сообщение отредактировал breeve - 28.12.2009, 13:30
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.12.2009, 13:35
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(breeve @ 28.12.2009, 13:59) *
qDebug("Ate key press %d", keyEvent->key());
и сравнить с кодом нужной клавиши (см. Qt::Key). Например:
if (event->type() == QEvent::KeyPress) {
    QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
    int k = keyEvent->key();
    if ((k & Qt::Key_Return) || (k & Qt::Key_Enter))
    {
        // что-то делаем
        return true;
    }
    
}
return QObject::eventFilter(obj, event);


Цитата(breeve @ 28.12.2009, 16:21) *
т.е пытаюсь что то ввести в текстЕдит он игнорит!
видимо ты true возвращаешь в качестве результата - это означает, что событие обработано. Т.е. обрабатывая любую кнопку ты говоришь, что следующему объекту, что событий для него нет.

П.С. надо проверить, как сравнивать, по абсолютной величине ("==") или по маске ("&"), обычно по маске.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
breeve
  опции профиля:
сообщение 28.12.2009, 13:50
Сообщение #7


Участник
**

Группа: Участник
Сообщений: 188
Регистрация: 26.12.2009
Пользователь №: 1336

Спасибо сказали: 9 раз(а)




Репутация:   1  


Цитата(Litkevich Yuriy @ 28.12.2009, 13:33) *
Цитата(breeve @ 28.12.2009, 13:59) *
qDebug("Ate key press %d", keyEvent->key());
и сравнить с кодом нужной клавиши (см. Qt::Key). Например:
if (event->type() == QEvent::KeyPress) {
    QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
    int k = keyEvent->key();
    if ((k & Qt::Key_Return) || (k & Qt::Key_Enter))
    {
        // что-то делаем
        return true;
    }
    
}
return QObject::eventFilter(obj, event);


Цитата(breeve @ 28.12.2009, 16:21) *
т.е пытаюсь что то ввести в текстЕдит он игнорит!
видимо ты true возвращаешь в качестве результата - это означает, что событие обработано. Т.е. обрабатывая любую кнопку ты говоришь, что следующему объекту, что событий для него нет.


Сделал так же.. опять не правильно.. что не нажимаю то происходит mySlot()
и еще if ((k & Qt::Key_Return) || (k & Qt::Key_Enter)) если в этой строке поменять с & на ==,
то будет работать опять таки только ентер(


:huh:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.12.2009, 13:54
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


breeve, не цитируй, целыми сообщениями, см. здесь, как цитировать частями.

Цитата(breeve @ 28.12.2009, 16:36) *
то будет работать опять таки только ентер(
хм, странно, надо подумать
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
breeve
  опции профиля:
сообщение 28.12.2009, 14:43
Сообщение #9


Участник
**

Группа: Участник
Сообщений: 188
Регистрация: 26.12.2009
Пользователь №: 1336

Спасибо сказали: 9 раз(а)




Репутация:   1  


Цитата(Litkevich Yuriy @ 28.12.2009, 13:54) *
breeve, не цитируй, целыми сообщениями, см. здесь, как цитировать частями.

Ок, Босс!!)) Буду знать..

А насчет моей проблемы т.е получается если я буду делать именно этим методом, то мне придется описывать каждую букву чтобы она печаталась.. Ну это конечно бред..
Выходит мне необходимо создать и отлавливать событие только на нажатие кнопки ентер. Осталось узнать как это сделать)

Сообщение отредактировал breeve - 28.12.2009, 14:44
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 28.12.2009, 16:10
Сообщение #10


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


breeve, зазипуй и выложи свой проект.

я понял свою ошибку, если не Ентер, то нужно вернуть false. Т.е.:
if (event->type() == QEvent::KeyPress) {
    QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
    int k = keyEvent->key();
    if ((k == Qt::Key_Return) || (k == Qt::Key_Enter))
    {
        // что-то делаем
        return true; // [0]
        
    }
    return false; // [1]
}
return false; // [2]


пояснение:
[0] возвращаем true если просто хотим закончить обработку событий прямо здесь, т.е. объект которому событие предназаначалось это событие не получит. Ентер как будто для него и не нажимали.
Если хотим чтобы целевой объект получил событие нажатия Ентер, то два варианта:
А) вернуть false
Б) вернуть BaseClass::eventFilter(obj, event), где BaseClass - базовый клас ЭТОГО класса.

[1] возвращаем false, тем самым говорим, что мы отказываемся от обработки здесь других кнопок, кроме Ентера, пусть их обрабатывает целевой объект.
В данном случае действуют те-же варианты А и Б.

[2] возвращаем false, тем самым говорим, что мы отказываемся от обработки здесь всего остального, пусть их обрабатывает целевой объект.
В данном случае действуют те-же варианты А и Б.

я думаю, что вместо возвращения false (вариант А), лучше использовать вариант Б, т.к. базовый клас может иметь свой (переопределённый) обработчик eventFilter
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 20.4.2024, 3:19