молча передать keyPressEvent одному дочернему элементу и сфокусировать его?

Когда пользователь вводит в окне на основе 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;
    }

person daisy    schedule 09.10.2011    source источник


Ответы (3)


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

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

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

lineEdit.setText( lineEdit.text() + event->text() );
person Chris    schedule 09.10.2011
comment
QCoreApplication::sendEvent() происходит немедленно, и в документе указано, что указатель не удален. Так что вы можете это сделать. - person galinette; 29.01.2014

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

person galinette    schedule 29.01.2014

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

person j_kubik    schedule 09.10.2011