Как запретить QWebEngineView захватывать фокус на вызовах setHtml() и load()?

Я создал простой макет окна Qt с QTreeView и QWebEngineView: после выбора некоторого элемента в древовидном представлении в представлении веб-движка отображается некоторый контент. Проблема в том, что при вызове QWebEngineView::setHtml(...) или load(...) древовидное представление теряет фокус клавиатуры, а представление веб-движка получает его. Это вызывает трудности при выборе элементов с помощью клавиатуры в древовидном представлении. Итак, как предотвратить потерю фокуса древовидного представления?

Я пытался использовать QTextBrowser вместо QWebEngineView. У него нет этой проблемы, но он не подходит для сложных HTML-страниц.


person Rimas    schedule 13.04.2016    source источник


Ответы (3)


Предположим, у нас есть:

QWebEngineView *webView = new QWebEngineView;

Для Qt 5.8 и новее

Проблема может быть решена путем настройки параметров:

webView->settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);

Пример кода: https://github.com/rmisev/FocusWidget/tree/if-qt-5.8

Ссылки:

Для Qt 5.7 и ранее

Самое простое решение (также указанное @Netrix) - это вызвать:

webView->setEnabled(false);

Но это отключает ввод с клавиатуры в webView.

Чтобы решить эту проблему, я создал простой класс FocusWidget в качестве родительского виджета для webView, который работает следующим образом:

  1. Изначально он отключает webView (webView->setEnabled(false)), поэтому не позволяет сосредоточиться на вызовах load(...), setHtml(...).
  2. Когда FocusWidget получает фокус, он включает и перенаправляет фокус на webView, поэтому разрешает ввод с клавиатуры.
  3. Когда webView и его дочерние элементы теряют фокус, FocusWidget снова отключает webView

Исходный код и пример приложения: https://github.com/rmisev/FocusWidget.

person Rimas    schedule 29.05.2016
comment
Я думаю, что это слишком сложное решение, поскольку вы можете обойти проблему, отключив веб-просмотр, вызвав reload() или setHtml(), а затем повторно включив его в трех строках кода! Я бы не понял этого без этого ответа. - person aatwo; 12.12.2016
comment
Мне нравится опечатка (я думаю?) в вашем ответе для Qt 5.8 и никогдаver, ха-ха, потому что это можно интерпретировать как не делайте этого ^^ - person Amine Kchouk; 03.04.2021

Я столкнулся с той же проблемой в своем приложении в PyQt5. Что мне удалось сделать, так это отключить весь виджет следующим образом (в Python):

view = PyQt5.QtWebEngineWidgets.QWebEngineView()
view.setEnabled(False)

Это привело к тому, что представление стало работать с помощью мыши (оно принимает щелчки мыши, и все можно изменить на веб-странице), но я не буду фокусироваться на другом виджете.

Я бы определенно назвал это ошибкой, а не функцией в QtWebEngineWidgets.

person Netrix    schedule 26.05.2016
comment
+1 за ответ. В начале я тоже думал о таком решении, но поскольку оно отключает ввод с клавиатуры в QWebEngineView, я думал, как обойти этот недостаток. Я разместил свое решение. - person Rimas; 29.05.2016

Спасибо всем остальным, кто дал ответы на это. Столкнувшись с этой ошибкой, я был несколько озадачен, но, узнав, как setEnabled(false) влияет на кражу фокуса из других ответов, я обнаружил, что простое отключение веб-просмотра, настройка html или его перезагрузка, а затем повторное включение позволяет обойти проблему. (по крайней мере, в Qt 5.7):

I.E.

myWebView->setEnabled( false );
myWebView->setHtml( html );
myWebView->setEnabled( true );

or

myWebView->setEnabled( false );
myWebView->reload();
myWebView->setEnabled( true );

Это позволяет вам решить проблему без необходимости создавать подклассы, как предлагает один из других ответов.

person aatwo    schedule 11.12.2016