3
votes

In QML only a single object can have keyboard focus (per window). In my application, I need the option of having multiple objects with keyboard focus, thus I use a custom event dispatcher in combination with a custom multiple selection implementation.

The problem is however that every time any of the stock Control elements are clicked, they automatically steal the focus, breaking the custom event dispatcher.

In addition to that, it still needs to be possible to explicitly set another focus item, in the case of overlay popups and such.

2

2 Answers

2
votes

I'm not sure how it fits in with your custom event stuff, but this answer might also help others who have found your question but are simply looking to prevent a control from getting focus.

You can prevent controls from getting focus with the focusPolicy enum:

Button {
    focusPolicy: Qt.NoFocus
    // Other options:
    // focusPolicy: Qt.TabFocus - The control accepts focus by tabbing.
    // focusPolicy: Qt.ClickFocus - The control accepts focus by clicking.
    // focusPolicy: Qt.StrongFocus - The control accepts focus by both tabbing and clicking.
    // focusPolicy: Qt.WheelFocus - The control accepts focus by tabbing, clicking, and using the mouse wheel.
}
0
votes

I ended up with this interface, applied to all focus-able items:

Item {
  onFocusChanged: if (keepFocus) focus = true
  property bool keepFocus: false
  property Item prevFocus: null
  function getFocus() {
    if (prevFocus) {
      prevFocus.keepFocus = false
      keepFocus = true
      focus = true
    }
  }
  function restoreFocus() {
    if (prevFocus) {
      keepFocus = false
      prevFocus.keepFocus = true
      prevFocus.focus = true
    }
  }
}

Since only overlay dialogs are supposed to take focus from the event dispatcher, the dialog base type automatically handles the acquiring and restoring of focus on dialog show and hide respectively.

So from "one item may have focus" I move to a "one item may have explicit focus", causing the focus to be re-enabled for that item whenever a Control element might steal it.