Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

SetFocus does not set focus to focusable QGraphicsItem



  • It is known that SetFocus on a QGraphicsItem will fail if it is not focusable ( e.g. http://permalink.gmane.org/gmane.comp.lib.qt.general/19804 ), which some are by default.

    When I use SetFocus on a focusable QGraphicsRectItem that is member of a scene and has been visible, hasFocus still returns false:

    @
    QGraphicsRectItem item;
    assert(item.flags() && QGraphicsItem::ItemIsFocusable);
    assert(item.scene());
    assert(item.isVisible());

    assert(!item.hasFocus()); //No focus yet

    item.setFocus(); //Set focus

    //View item, force painting of item to image, just to get it work

    assert(item.hasFocus()); //Why does this fail?
    @

    I am using Qt Creator 3.1.1 based on Qt 5.3.0 using GCC 4.9.1 (the 32 bit version).

    A full compilable example:

    @
    #include <cassert>
    #include <QApplication>
    #include <QGraphicsView>
    #include <QGraphicsRectItem>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);

    QGraphicsScene scene;
    QGraphicsView view(&scene);
    view.setGeometry(100,100,400,100);

    QGraphicsRectItem item;
    item.setFlags(
    QGraphicsItem::ItemIsSelectable
    | QGraphicsItem::ItemIsFocusable
    );

    item.setRect(-20,-10,40,20);

    scene.addItem(&item);

    assert(item.flags() && QGraphicsItem::ItemIsSelectable);
    assert(item.flags() && QGraphicsItem::ItemIsFocusable);
    assert(item.scene());
    assert(item.isVisible());

    assert(!item.hasFocus()); //No focus yet

    item.setFocus(); //Set focus

    view.show(); //Show it

    //Force paint of item
    {
    QImage image(scene.sceneRect().size().toSize(), QImage::Format_ARGB32);
    image.fill(Qt::transparent);
    QPainter painter(&image);
    scene.render(&painter);
    image.save("tmp.png");
    }

    assert(item.hasFocus()); //Why does this fail?

    return a.exec();
    }
    @

    Thanks for your suggestions, Richel Bilderbeek


  • Lifetime Qt Champion

    Hi,

    Following's setFocus documentation, it seems that you are in the case described here:
    [quote]If this item is not visible, not active, or not associated with a scene, it will not gain immediate input focus. However, it will be registered as the preferred focus item for its subtree of items, should it later become visible.
    [/quote]



  • Ah, excellent reply! In the full example, I do make it an item of a QGraphicsScene. So what could it else be? (note: I modified it in the original code snippet)


  • Lifetime Qt Champion

    The item is still not visible when you call setFocus



  • Even when I force the item to be painted to an image, it never gets focus as well (I added this to the code). Perhaps a QGraphicsItem can only get focus when shown on screen, yet I want to avoid this: the ultimate goal is to test if a (derived class of) QGraphicsItem looks different with or without focus.


  • Lifetime Qt Champion

    Painted and visible is not the same thing. Why do you need that look information ?



  • I want to test that a focused QGraphicsItem is drawn correctly for debugging purposes. For example, it should be different than an unfocused QGraphicsItem, as it might have a dashed edge.


  • Lifetime Qt Champion

    Ok but you can't expect an invisible widget to get focus. What would be the problem to show that scene for your test ?



  • I want to do some basic debugging tests, for example, to check that an item with focus is drawn differently than an item without focus.

    Assuming you are right, I guess the tester will have to deal with some screens that pop up very shortly.

    Thanks for the help!


  • Lifetime Qt Champion

    That's also what happens currently with some of the tests created for Qt


Log in to reply