молча передать keyPressEvent одному дочернему элементу, и заставить его фокусироваться? - PullRequest
1 голос
/ 09 октября 2011

Когда пользователь печатает в окне на основе QWidget, я хотел, чтобы QLineEdit обработал все клавиши ввода, поэтому я попробовал следующие два решения в keyPressEvent() этого QWidget:

A.

void Window::keyPressEvent (QKeyEvent *e)
{
   switch (e->key())
   {
     // handle other short cuts
     default:
       QApplication::sendEvent (lineEdit , e);
       break;
   }
}

Ну, иногда это вызывает сбой всего интерфейса, особенно когда я resize window.

B.

void Window::keyPressEvent (QKeyEvent *e)
{
   switch (e->key())
   {
     // handle other short cuts
     default:

     if ( ! lineEdit.hasFocus () )
     {
        lineEdit.setFocus ();
        lineEdit.setText (e->key()); 
        // i wanted to push the first key input to that QLineEdit , but how ?
        // or i'll miss it
     }
     break;
   }
}

Также я думаю о предоставленииlineEdit фокусируется все время, но я не могу этого сделать, так как другие события должны обрабатываться главным пользовательским интерфейсом.

Обновление

Не произойдет сбой при фильтрации ключевых входова почему?

 default:
        if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete ||
                (e->key() >= Qt::Key_A && e->key() <= Qt::Key_Z )
                )
            QApplication::sendEvent(filter , e);
        break;
    }

Ответы [ 3 ]

1 голос
/ 10 октября 2011

Я полагаю, что вы столкнулись с сбоем, потому что вы используете sendEvent для отправки объекта события, над которым у вас нет контроля.

Я не думаю, что система событий Qt ожидает, что вы захватите ее события и выбросите их в других направлениях, и вполне вероятно, что объект события разрушается до того, как ожидается редактирование строки. В случае, когда вы фильтруете клавиши ввода, это, вероятно, не дает сбоя, потому что редактирование строки не заботится о таких видах нажатий клавиш и не использует объект события так, как это было бы иначе.

Если вы действительно хотите использовать функциональность sendEvent(), я бы посоветовал вам создать свой собственный QKeyEvent в стеке и передать его в функцию sendEvent() (как показано здесь ), или вы можно просто сделать что-то вроде этого:

lineEdit.setText( lineEdit.text() + event->text() );
0 голосов
/ 29 января 2014

Когда виджет не обрабатывает событие, он пересылает его своему родителю. Поэтому использование sendEvent () для пересылки потомку опасно, так как может создать рекурсию.

0 голосов
/ 09 октября 2011

Самый простой способ сделать это - использовать QKeyEvent::text вместо QKeyEvent::key, и с вами все будет в порядке.Вы также можете попытаться создать копию QKeyEvent и передать ее в QLineEdit.Хотя это скорее взломы, чем решения.Если вам нужны ярлыки в главном окне, когда QLineEdit имеет фокус (при условии, что он находится в этом окне), вы можете использовать QShortcut с контекстом Qt::WidgetWithChildrenShortcut - таким образом вы можете поддерживать LineEdit активным всегда.

...