如何防止 QWebEngineView 将焦点集中在 setHtml(...) 和 load(...) 调用上?
How to prevent QWebEngineView to grab focus on setHtml(...) and load(...) calls?
我用 QTreeView
和 QWebEngineView
创建了简单的 Qt Window 布局:在树视图中选择一些项目后,Web 引擎视图显示一些内容。问题是当 QWebEngineView::setHtml(...)
或 load(...)
被调用时树视图失去键盘焦点而 Web 引擎视图获得它。这会导致在树视图中使用键盘选择项目时出现困难。那么,如何防止树视图焦点丢失呢?
我尝试使用 QTextBrowser
而不是 QWebEngineView
。它没有这个问题,但它不适合复杂的 HTML 页面。
我在 PyQt5 的应用程序中遇到了同样的问题。我设法做的是像这样禁用整个小部件(在 Python 中):
view = PyQt5.QtWebEngineWidgets.QWebEngineView()
view.setEnabled(False)
这导致视图可以使用鼠标操作(它接受鼠标点击并且可以在网页上更改内容)但我不会从其他小部件获取焦点。
在 QtWebEngineWidgets 中,我肯定会称它为错误而不是功能。
假设我们有:
QWebEngineView *webView = new QWebEngineView;
对于 Qt 5.8 和更新版本
问题可以通过调整设置来解决:
webView->settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
示例代码:https://github.com/rmisev/FocusWidget/tree/if-qt-5.8
参考文献:
- QWebEngineView::settings()
- QWebEngineSettings Class
- QWebEngineSettings::setAttribute(WebAttribute attribute, bool on)
- QTBUG-52999
对于 Qt 5.7 及更早版本
最简单的解决方案(也由@Netrix 指出)是调用:
webView->setEnabled(false);
但这会禁用对 webView
的键盘输入。
为了解决这个问题,我创建了简单的 FocusWidget
class 作为 webView
的父窗口小部件,其工作方式如下:
- 最初它会禁用
webView
(webView->setEnabled(false)
),因此会阻止关注 load(...)
、setHtml(...)
调用。
- 当
FocusWidget
获得焦点时,它启用并将焦点转发到 webView
,因此启用键盘输入。
- 当
webView
及其子项失去焦点时,FocusWidget
再次禁用 webView
源代码和示例应用程序:https://github.com/rmisev/FocusWidget
感谢为此提供答案的所有其他人。遇到这个错误后,我有点难过,但是在了解了 setEnabled(false) 影响从其他答案窃取焦点的方式后,我发现只需禁用 webview,设置 html 或重新加载它,然后重新启用它规避了这个问题(至少在 Qt 5.7 中):
I.E.
myWebView->setEnabled( false );
myWebView->setHtml( html );
myWebView->setEnabled( true );
或
myWebView->setEnabled( false );
myWebView->reload();
myWebView->setEnabled( true );
这使您可以解决问题,而无需像其他答案之一所建议的那样对任何内容进行子类化。
我用 QTreeView
和 QWebEngineView
创建了简单的 Qt Window 布局:在树视图中选择一些项目后,Web 引擎视图显示一些内容。问题是当 QWebEngineView::setHtml(...)
或 load(...)
被调用时树视图失去键盘焦点而 Web 引擎视图获得它。这会导致在树视图中使用键盘选择项目时出现困难。那么,如何防止树视图焦点丢失呢?
我尝试使用 QTextBrowser
而不是 QWebEngineView
。它没有这个问题,但它不适合复杂的 HTML 页面。
我在 PyQt5 的应用程序中遇到了同样的问题。我设法做的是像这样禁用整个小部件(在 Python 中):
view = PyQt5.QtWebEngineWidgets.QWebEngineView()
view.setEnabled(False)
这导致视图可以使用鼠标操作(它接受鼠标点击并且可以在网页上更改内容)但我不会从其他小部件获取焦点。
在 QtWebEngineWidgets 中,我肯定会称它为错误而不是功能。
假设我们有:
QWebEngineView *webView = new QWebEngineView;
对于 Qt 5.8 和更新版本
问题可以通过调整设置来解决:
webView->settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
示例代码:https://github.com/rmisev/FocusWidget/tree/if-qt-5.8
参考文献:
- QWebEngineView::settings()
- QWebEngineSettings Class
- QWebEngineSettings::setAttribute(WebAttribute attribute, bool on)
- QTBUG-52999
对于 Qt 5.7 及更早版本
最简单的解决方案(也由@Netrix 指出)是调用:
webView->setEnabled(false);
但这会禁用对 webView
的键盘输入。
为了解决这个问题,我创建了简单的 FocusWidget
class 作为 webView
的父窗口小部件,其工作方式如下:
- 最初它会禁用
webView
(webView->setEnabled(false)
),因此会阻止关注load(...)
、setHtml(...)
调用。 - 当
FocusWidget
获得焦点时,它启用并将焦点转发到webView
,因此启用键盘输入。 - 当
webView
及其子项失去焦点时,FocusWidget
再次禁用webView
源代码和示例应用程序:https://github.com/rmisev/FocusWidget
感谢为此提供答案的所有其他人。遇到这个错误后,我有点难过,但是在了解了 setEnabled(false) 影响从其他答案窃取焦点的方式后,我发现只需禁用 webview,设置 html 或重新加载它,然后重新启用它规避了这个问题(至少在 Qt 5.7 中):
I.E.
myWebView->setEnabled( false );
myWebView->setHtml( html );
myWebView->setEnabled( true );
或
myWebView->setEnabled( false );
myWebView->reload();
myWebView->setEnabled( true );
这使您可以解决问题,而无需像其他答案之一所建议的那样对任何内容进行子类化。