Определить источник QKeyEvent

У меня есть приложение Qt с несколькими виджетами, показывающими кнопки одновременно. В определенных обстоятельствах я хочу, чтобы нажатия клавиш отправлялись на один из виджетов, даже если этот виджет не имеет фокуса. Для этого я переопределил keyPressEvent() в главном виджете (который владеет всеми подвиджетами в этом приложении) и повторно отправил ключевое событие в подвиджет, если он не имеет фокуса, используя код, подобный этому:

if (!someWidget->hasFocus())
{
    QApplication::sendEvent(someWidget, keyEvent);
}

Это прекрасно работает, пока someWidget передает указанное событие. Если он игнорирует его, то входит в неприятный бесконечный рекурсивный цикл, поскольку события переходят к родителям.

Есть ли способ узнать, откуда произошло событие, чтобы я мог предотвратить этот бесконечный цикл? Я думаю о чем-то вроде этого:

if (!someWidget->hasFocus() && (keyEvent->source != someWidget))
{
    QApplication::sendEvent(someWidget, keyEvent);
}

Или есть другой способ предотвратить это?


person KyleL    schedule 22.09.2014    source источник
comment
QApplication::focusWidget? Имхо, источником QKeyEvent является пользователь -> API платформы.   -  person Dmitry Sazonov    schedule 23.09.2014


Ответы (1)


Когда вы используете механизм сигналов и слотов, вы можете вызвать sender(), который может дать вам информацию, но здесь вы можете сделать следующее: используйте eventFilter, который может дать вам информацию о каждом QObject, который отправляет события в mainWindow, чтобы вы могли перехватить событие и отправителя.

    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
    if(event->type() == QEvent::KeyPress)//your keyPressEvent but with eventFilter
        if(!someWidget->hasFocus() && obj != someWidget)//your focus and source checkings, obj is object which send some event,
                                                        // but eventFilter catch it and you can do something with this info
        {   
        //do something, post event
        }

return QObject::eventFilter(obj, event);
}

Не забывайте

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

Возможно, вам нужно использовать QKeyEvent, так что используйте QEvent, если вы уверены, что event->type() == QEvent::KeyPress. Например:

QKeyEvent *key = static_cast<QKeyEvent*>(event);
if(key->key() == Qt::Key_0)
{
    //do something
}
person Kosovan    schedule 22.09.2014
comment
Похоже, что в eventFilter(QObject *obj, QEvent *event) 'obj' - это отслеживаемый объект, а не объект, отправляющий событие. Знаете ли вы, есть ли способ определить источник события? - person KyleL; 23.09.2014
comment
@KyleL каковы обстоятельства? Вы выбираете, когда делать это или это действия пользователя? Возможно, вы можете сделать это с помощью слотов сигналов и использовать sender() - person Kosovan; 23.09.2014
comment
@KyleL, а что ты хочешь сделать? Отловить нажатие и установить текст в другие textEdits что ли? - person Kosovan; 23.09.2014