[Interest] QML: Changing focus when clicking outside a focused Item

Daiwei Li daiweili at gmail.com
Fri Jul 12 21:03:38 CEST 2013


Hi everyone,

I'm wondering if there is a recommended way to relinquish focus from an
Item (or rather, give focus to a pre-determined item) if you click outside
of it.

Consider the following example:

import QtQuick 2.0


Item {

    id: root

    width: 600

    height: 300


    Rectangle {

        id: rect1

        width: 240

        height: 240

        border.width: 1

        border.color: 'black'

        MouseArea {

            anchors.fill: parent

            onClicked: {

                rect1.forceActiveFocus();

                rect1.color = 'red';

            }

        }

        Keys.onPressed: {

            rect1.color = 'green';

            event.accepted = true;

        }

    }

    Rectangle {

        id: rect2

        width: 240

        height: 240

        border.width: 1

        border.color: 'black'

        x: 250

        Keys.onPressed: {

            rect2.color = 'blue';

        }


    }


    Keys.forwardTo: [rect2]

}


After clicking on the first rectangle, it's no longer possible to turn the
second rectangle blue by typing any keys. I would like to make it so that
clicking anywhere outside rect1 lets me set the color on rect2.

If I add a MouseArea to root that gives it focus when you click on it, this
works fine as long as other Items in the scene don't have MouseAreas of
their own. I would like to make sure that clicking anywhere in the root
item gives focus to it, except for areas such as rect1, where it forces
focus on itself when you click on it. i.e., adding to root:

    MouseArea {

        anchors.fill: parent

        onClicked: {

            root.forceActiveFocus();

        }

    }


works fine, until I also add to rect2, at which point clicking in rect2 no
longer sets focus on root:

    MouseArea {

        anchors.fill: parent

        onClicked: {

	    console.log('clicked in rect2');

        }

    }



I attempted to solve this by adding a click handler to MouseArea that looks
for the nearest parent with a property "defaultFocusItem". This would make
all mouse clicks focus to this parent. Something like:

import QtQuick 2.0


MouseArea {

  id: root


  function findParent(child, propertyName) {

      if (!child)

          return null

      var next = child.parent

      while (next && !next.hasOwnProperty(propertyName))

          next = next.parent

      return next

  }


  Connections {

    onClicked: {

      var item = findParent(root, 'defaultFocusItem');

      if (item.defaultFocusItem)

      {

        item.forceActiveFocus();

      }

    }

  }

}


Unfortunately, this doesn't always work as expected. If the click handler
in this MouseArea is executed after the click handler in the rectangle, the
focus is set on the wrong item (e.g. root instead of rect1 when clicking in
rect1!). It also causes unnecessary forceActiveFocus calls even if the
focus ends up at the right place.

Thanks in advance for any suggestions!

Daiwei
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20130712/febfea8d/attachment.html>


More information about the Interest mailing list