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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Переход к следующему виджету по Enter  (Прочитано 3829 раз)
alex_beginner
Гость
« : Январь 13, 2012, 13:38 »

Не пойму, как мне сделать переход к следующему виджету по Enter (вместо Tab).
У некоторых виджетов есть сигнал ReturnPressed, а у других-то нет.
Ну и даже если есть сигнал, как мне устанавливать не фокус конкретного виджета, а именно сказать "перейди к следующему"?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Январь 13, 2012, 13:41 »

Начинай отсюда читать http://doc.qt.nokia.com/4.8-snapshot/qkeyevent.html.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
alex_beginner
Гость
« Ответ #2 : Январь 13, 2012, 20:40 »

Мда, "Уж послала, так послала..." (с)  Смеющийся

Ну, зато закаляет характер. А для лентяев (коим и сам я являюсь) опишу, как я это сделал. Может не оптимально, но работает.

1. Создаем фильтр событий окна. Там интуитивно по названию закорючек всё примерно понятно (даже мне). Это я честно списал у кого-то в инете:
Код:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() != QEvent::KeyPress)
    {
        return QObject::eventFilter(obj, event);
    }
    QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
    switch (keyEvent->key()) {
    case Qt::Key_Return:
    case Qt::Key_Enter:
        if (focusNextChild()) {
            return true;
        }
        return false;
    default:
        return QObject::eventFilter(obj, event);
    }
}
2. Теперь надо инсталлировать этот фильтр для каждого нужного нам виджета (у которого д.б. такое поведение). Как сделать - на любителя, я себе написал функцию такого вида:
Код:
void MainWindow::InstallEventFilters(QObject * obj,...)
{
    va_list args;
    for(va_start(args,obj);obj;obj->installEventFilter(this),obj = va_arg(args,QObject *));
}
Ей передаётся любое число указателей на виджеты (но не меньше одного), которым надо инсталлировать обработчик. Последним элементом (признаком конца) в передаваемом списке должен быть NULL

3. В конструкторе формы вызываем что-то вроде этого:
Код:
InstallEventFilters(ui->DateCreateBegin,ui->DateCreateEnd,ui->TimeCreateBegin,ui->TimeCreateEnd,NULL);

Всё - перечисленные в вызове виджеты приобретают нужное нам поведение. Пока вроде работает.
Записан
alex_beginner
Гость
« Ответ #3 : Январь 13, 2012, 21:12 »

... однако, не всё так уж замечательно.
Если при переходе по Tab прорисовка радиокнопок и чекбоксов нормальная, то при переходе по Enter почему-то у них не появляется никакая рамочка, как будто фокус не установлен. Хотя реально установлен.
А если по форме хотя бы раз пройтись TABом, то потом уже и Enter-ом ходит нормально. Странно это.

Почему так, и как бороться? Можно ли как-то просто подменить код нажатой клавиши (чтоб он думал, что я просто TAB нажимаю)?  Если да, где это сделать и как?
Записан
andrew.k
Гость
« Ответ #4 : Январь 13, 2012, 23:37 »

Вот написал тестовый проект.
Нажатый ентер заменяется на таб.

Код
C++ (Qt)
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
   if(event->type() == QEvent::KeyPress)
   {
       QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
       if(keyEvent->key() == Qt::Key_Return)
       {
           QKeyEvent ke(QEvent::KeyPress,Qt::Key_Tab,Qt::NoModifier);
           //QCoreApplication::sendEvent(this,&ke);
           QWidget::event(&ke);
           return true;
       }
   }
   return QWidget::eventFilter(watched,event);
}
 

Работают оба варианта кстати.
Теоретически QWidget::event наверное быстрее будет работать?
Или вообще не стоит так делать? Вопрос к знатокам.
Код
C++ (Qt)
           //QCoreApplication::sendEvent(this,&ke);
           QWidget::event(&ke);
 
Записан
alex_beginner
Гость
« Ответ #5 : Январь 14, 2012, 13:27 »

Вот этот вариант:
Код:
QCoreApplication::sendEvent(this,&ke);
у меня работает нормально, и рамочки вокруг кнопок рисуются как надо.
А вот этот
Код:
QWidget::event(&ke);
работает так же, как и мой пример - немного косяково.
Ну это может особенности Windows, в других средах пока не смотрел, как оно там.

Спасибо. То, что надо.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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