Pass Events Between QML Objects

4k views Asked by At

I have a situation where I would like to pass a QML event to another QML item in the middle of the initial event handler. e.g.

Item {
   id: item1

   Keys.onPressed: {
      // Pre-process...

      passEventToObject(event, item2);

      // Post-process based on results of event passing...
   }
}

TextInput {
   id: item2
   // Expect key press event to be handled by text input
}

What can I do to acheive passEventToObject?

Notes:

  • I don't have access to modify Keys.onPressed inside item2, it's a QML built-in (TextInput).
  • The event passing must happen in the middle of item1.Keys.onPressed
3

There are 3 answers

1
spbots On BEST ANSWER

One method to move events between Items is to create a C++ plugin and use QCoreApplication::sendEvent. Unfortunately, Qt doesn't map directly from the QML KeyEvent and the C++ QKeyEvent, so the interface to the plugin will need to expose the internals of the event:

bool EventRelay::relayKeyPressEvent(
   int key,
   Qt::KeyboardModifiers modifiers,
   const QString& text,
   bool autoRepeat,
   ushort count) const
{
   QKeyEvent event(QKeyEvent::KeyPress, key, modifiers, text, autoRepeat, count);
   return relayEventToObject(&event, mpTargetObject);
}

To use it:

EventRelay { id: relay }

Item {
   id: item1
   Keys.onPressed: {
      // Pre-process...

      relay.relayEventToObject(event, item2);

      // Post-process...
   }
}

TextInput {
   id: item2
}
2
BaCaRoZzo On

I think it could be useful the section "Signal to Signal Connect" that you can find here. Basically, each signal has a connect method which can be exploited to create a signals chain.

If you are interested to forword key events (as in your example) consider instead the forwardTo property:

This property provides a way to forward key presses, key releases, and keyboard input coming from input methods to other items. This can be useful when you want one item to handle some keys (e.g. the up and down arrow keys), and another item to handle other keys (e.g. the left and right arrow keys). Once an item that has been forwarded keys accepts the event it is no longer forwarded to items later in the list.

The documentation provides a nice and simple example.

1
GrecKo On

You can simply invoke the other object's signal in your first object signal handler :

Item {
   id: item1
   Keys.onPressed: {
      // Pre-process...
      item2.Keys.pressed(event);
      // Post-process based on results of event passing...
   }
}

Item {
   id: item2
   Keys.onPressed: {
      // Some other stuff happens here
   }
}