Guest2016
Guest2016

Reputation: 21

QGraphicsScene, QTextEdit and lost focus

QTextEdit and similar widgets embedded in QGraphicsScene lose focus after using standard context menu (copy/paste), i. e. you need to click on QTextEdit again to continue editing. Scene emits focusItemChanged with newFocusItem==0.

First question: Is it a bug or standard behavior?

My investigation shows that function QGraphicsItemPrivate::setVisibleHelper() clears focus here:

if (hasFocus && scene) {
    // Hiding the focus item or the closest non-panel ancestor of the focus item
    QGraphicsItem *focusItem = scene->focusItem();
    bool clear = true;
    if (isWidget && !focusItem->isPanel()) {
        do {
            if (focusItem == q_ptr) {
                clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
                break;
            }
        } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
    }
    if (clear)
        clearFocusHelper(/* giveFocusToParent = */ false, hiddenByPanel);
}

QGraphisItem has undocumented (internal) flag QGraphicsItem::ItemIsFocusScope. If the flag is set for QTextEdit's proxy-item it gets focus back after menu, but in any case focus cleared at first and after that Item receives it again or not.

Second Question: What is flag QGraphicsItem::ItemIsFocusScope for?

Upvotes: 2

Views: 978

Answers (1)

Looks like QGraphicsItem::ItemIsFocusScope is for FocusScope QML item. QtQuick1 is QGraphicsScene based and used that flag.

I'm not sure about side effects but that helps:

auto edit = new QLineEdit();
auto item = scene->addWidget(edit);
item->setFlag(QGraphicsItem::GraphicsItemFlag::ItemIsPanel);

Tested on Qt 5.9, Linux


EDIT

For me looks as bug:

  • add QLineEdit to scene
  • click to focus QLineEdit
  • hit ContextMenu key to show context menu
  • hit Esc key to exit context menu
  • try to type

Expected: QLineEdit is focused and text appears

Actual: QLineEdit lost input focus

Please find it or report with Qt bug tracker

So it's OK to have workaround using QGraphicsItem::ItemIsFocusScope flag for example.

#if (QT_VERSION < QT_VERSION_CHECK(<fixed in Qt version>))
// it's workaround of bug QTBUG-...
#    if (QT_VERSION == QT_VERSION_CHECK(<version you are develop with>)
    item.setFlag(QGraphicsItem::ItemIsFocusScope);
#    else
#        error("The workaround is not tested on this version of Qt. Please run tests/bug_..._workaround_test")
#    endif

Upvotes: 1

Related Questions