aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEce Cinucen <[email protected]>2025-01-28 19:06:03 +0100
committerEce Cinucen <[email protected]>2025-01-30 14:57:33 +0100
commiteb80f8e29a06559c5b2d9c5dbded017a3f1e7039 (patch)
tree5ec2ec85a8fa4cb2f5b5fc607f698e4ad05c1dc7
parent78aedfbbc900f008e02ff73517f4c2b5e07cec30 (diff)
Example: Update simplebrowser
Pick-to: 6.8 Change-Id: Iaa596cb568f39cd9395f1a68030fa598b16c0787 Reviewed-by: Friedemann Kleint <[email protected]>
-rw-r--r--examples/webenginewidgets/simplebrowser/browser.py7
-rw-r--r--examples/webenginewidgets/simplebrowser/main.py9
-rw-r--r--examples/webenginewidgets/simplebrowser/ui_webauthdialog.py83
-rw-r--r--examples/webenginewidgets/simplebrowser/webauthdialog.py243
-rw-r--r--examples/webenginewidgets/simplebrowser/webauthdialog.ui151
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.py1
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.py32
7 files changed, 517 insertions, 9 deletions
diff --git a/examples/webenginewidgets/simplebrowser/browser.py b/examples/webenginewidgets/simplebrowser/browser.py
index 1bf458e79..29e452085 100644
--- a/examples/webenginewidgets/simplebrowser/browser.py
+++ b/examples/webenginewidgets/simplebrowser/browser.py
@@ -22,9 +22,6 @@ class Browser(QObject):
# remaining window
self._download_manager_widget.setAttribute(Qt.WidgetAttribute.WA_QuitOnClose, False)
- dp = QWebEngineProfile.defaultProfile()
- dp.downloadRequested.connect(self._download_manager_widget.download_requested)
-
def create_hidden_window(self, offTheRecord=False):
if not offTheRecord and not self._profile:
name = "simplebrowser." + qWebEngineChromiumVersion()
@@ -34,11 +31,15 @@ class Browser(QObject):
s.setAttribute(QWebEngineSettings.WebAttribute.DnsPrefetchEnabled, True)
s.setAttribute(QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, True)
s.setAttribute(QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, False)
+ s.setAttribute(QWebEngineSettings.ScreenCaptureEnabled, True)
self._profile.downloadRequested.connect(
self._download_manager_widget.download_requested)
profile = QWebEngineProfile.defaultProfile() if offTheRecord else self._profile
main_window = BrowserWindow(self, profile, False)
+ profile.setPersistentPermissionsPolicy(
+ QWebEngineProfile.PersistentPermissionsPolicy.AskEveryTime)
+
self._windows.append(main_window)
main_window.about_to_close.connect(self._remove_window)
return main_window
diff --git a/examples/webenginewidgets/simplebrowser/main.py b/examples/webenginewidgets/simplebrowser/main.py
index 2602c5db9..3d42974a7 100644
--- a/examples/webenginewidgets/simplebrowser/main.py
+++ b/examples/webenginewidgets/simplebrowser/main.py
@@ -16,6 +16,7 @@ from browser import Browser
import data.rc_simplebrowser # noqa: F401
+
if __name__ == "__main__":
parser = ArgumentParser(description="Qt Widgets Web Browser",
formatter_class=RawTextHelpFormatter)
@@ -34,13 +35,15 @@ if __name__ == "__main__":
QLoggingCategory.setFilterRules("qt.webenginecontext.debug=true")
s = QWebEngineProfile.defaultProfile().settings()
- s.setAttribute(QWebEngineSettings.WebAttribute.PluginsEnabled, True)
- s.setAttribute(QWebEngineSettings.WebAttribute.DnsPrefetchEnabled, True)
+ s.setAttribute(QWebEngineSettings.PluginsEnabled, True)
+ s.setAttribute(QWebEngineSettings.DnsPrefetchEnabled, True)
+ s.setAttribute(QWebEngineSettings.ScreenCaptureEnabled, True)
browser = Browser()
window = browser.create_hidden_window()
- url = QUrl.fromUserInput(args.url) if args.url else QUrl("https://www.qt.io")
+ url = QUrl.fromUserInput(args.url) if args.url else QUrl("chrome://qt")
window.tab_widget().set_url(url)
window.show()
+
sys.exit(app.exec())
diff --git a/examples/webenginewidgets/simplebrowser/ui_webauthdialog.py b/examples/webenginewidgets/simplebrowser/ui_webauthdialog.py
new file mode 100644
index 000000000..eb54ba64e
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/ui_webauthdialog.py
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'webauthdialog.ui'
+##
+## Created by: Qt User Interface Compiler version 6.8.1
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+ QMetaObject, QObject, QPoint, QRect,
+ QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+ QFont, QFontDatabase, QGradient, QIcon,
+ QImage, QKeySequence, QLinearGradient, QPainter,
+ QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QAbstractButton, QApplication, QDialog, QDialogButtonBox,
+ QGroupBox, QLabel, QLayout, QLineEdit,
+ QSizePolicy, QVBoxLayout, QWidget)
+
+class Ui_WebAuthDialog(object):
+ def setupUi(self, WebAuthDialog):
+ if not WebAuthDialog.objectName():
+ WebAuthDialog.setObjectName(u"WebAuthDialog")
+ WebAuthDialog.resize(563, 397)
+ self.buttonBox = QDialogButtonBox(WebAuthDialog)
+ self.buttonBox.setObjectName(u"buttonBox")
+ self.buttonBox.setGeometry(QRect(20, 320, 471, 32))
+ self.buttonBox.setOrientation(Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok|QDialogButtonBox.Retry)
+ self.m_headingLabel = QLabel(WebAuthDialog)
+ self.m_headingLabel.setObjectName(u"m_headingLabel")
+ self.m_headingLabel.setGeometry(QRect(30, 20, 321, 16))
+ self.m_headingLabel.setWordWrap(False)
+ self.m_description = QLabel(WebAuthDialog)
+ self.m_description.setObjectName(u"m_description")
+ self.m_description.setGeometry(QRect(30, 60, 491, 31))
+ self.m_description.setWordWrap(False)
+ self.layoutWidget = QWidget(WebAuthDialog)
+ self.layoutWidget.setObjectName(u"layoutWidget")
+ self.layoutWidget.setGeometry(QRect(20, 100, 471, 171))
+ self.m_mainVerticalLayout = QVBoxLayout(self.layoutWidget)
+ self.m_mainVerticalLayout.setObjectName(u"m_mainVerticalLayout")
+ self.m_mainVerticalLayout.setSizeConstraint(QLayout.SetDefaultConstraint)
+ self.m_mainVerticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.m_pinGroupBox = QGroupBox(self.layoutWidget)
+ self.m_pinGroupBox.setObjectName(u"m_pinGroupBox")
+ self.m_pinGroupBox.setFlat(True)
+ self.m_pinLabel = QLabel(self.m_pinGroupBox)
+ self.m_pinLabel.setObjectName(u"m_pinLabel")
+ self.m_pinLabel.setGeometry(QRect(10, 20, 58, 16))
+ self.m_pinLineEdit = QLineEdit(self.m_pinGroupBox)
+ self.m_pinLineEdit.setObjectName(u"m_pinLineEdit")
+ self.m_pinLineEdit.setGeometry(QRect(90, 20, 113, 21))
+ self.m_confirmPinLabel = QLabel(self.m_pinGroupBox)
+ self.m_confirmPinLabel.setObjectName(u"m_confirmPinLabel")
+ self.m_confirmPinLabel.setGeometry(QRect(10, 50, 81, 16))
+ self.m_confirmPinLineEdit = QLineEdit(self.m_pinGroupBox)
+ self.m_confirmPinLineEdit.setObjectName(u"m_confirmPinLineEdit")
+ self.m_confirmPinLineEdit.setGeometry(QRect(90, 50, 113, 21))
+ self.m_pinEntryErrorLabel = QLabel(self.m_pinGroupBox)
+ self.m_pinEntryErrorLabel.setObjectName(u"m_pinEntryErrorLabel")
+ self.m_pinEntryErrorLabel.setGeometry(QRect(10, 80, 441, 16))
+
+ self.m_mainVerticalLayout.addWidget(self.m_pinGroupBox)
+
+
+ self.retranslateUi(WebAuthDialog)
+
+ QMetaObject.connectSlotsByName(WebAuthDialog)
+ # setupUi
+
+ def retranslateUi(self, WebAuthDialog):
+ WebAuthDialog.setWindowTitle(QCoreApplication.translate("WebAuthDialog", u"Dialog", None))
+ self.m_headingLabel.setText(QCoreApplication.translate("WebAuthDialog", u"Heading", None))
+ self.m_description.setText(QCoreApplication.translate("WebAuthDialog", u"Description", None))
+ self.m_pinGroupBox.setTitle("")
+ self.m_pinLabel.setText(QCoreApplication.translate("WebAuthDialog", u"PIN", None))
+ self.m_confirmPinLabel.setText(QCoreApplication.translate("WebAuthDialog", u"Confirm PIN", None))
+ self.m_pinEntryErrorLabel.setText(QCoreApplication.translate("WebAuthDialog", u"TextLabel", None))
+ # retranslateUi
+
diff --git a/examples/webenginewidgets/simplebrowser/webauthdialog.py b/examples/webenginewidgets/simplebrowser/webauthdialog.py
new file mode 100644
index 000000000..162c595d2
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webauthdialog.py
@@ -0,0 +1,243 @@
+# Converted from webauthdialog.cpp
+
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from ui_webauthdialog import Ui_WebAuthDialog
+
+from PySide6.QtWidgets import (QDialog, QVBoxLayout, QButtonGroup,
+ QScrollArea, QWidget, QDialogButtonBox,
+ QSizePolicy, QRadioButton)
+from PySide6.QtCore import Qt
+from PySide6.QtWebEngineCore import QWebEngineWebAuthUxRequest
+
+
+class WebAuthDialog(QDialog):
+
+ def __init__(self, request, parent=None):
+ super().__init__(parent)
+
+ self.uxRequest = request
+ self.uiWebAuthDialog = Ui_WebAuthDialog()
+ self.uiWebAuthDialog.setupUi(self)
+
+ self.button_group = QButtonGroup(self)
+ self.button_group.setExclusive(True)
+
+ self.scroll_area = QScrollArea(self)
+ self.select_account_widget = QWidget(self)
+ self.scroll_area.setWidget(self.select_account_widget)
+ self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+ self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
+ self.select_account_widget.resize(400, 150)
+
+ self.select_account_layout = QVBoxLayout(self.select_account_widget)
+ self.uiWebAuthDialog.m_mainVerticalLayout.addWidget(self.scroll_area)
+ self.select_account_layout.setAlignment(Qt.AlignTop)
+
+ self.update_display()
+
+ self.uiWebAuthDialog.buttonBox.rejected.connect(self.onCancelRequest)
+ self.uiWebAuthDialog.buttonBox.accepted.connect(self.onAcceptRequest)
+
+ button = self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Retry)
+ button.clicked.connect(self.onRetry)
+ self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
+
+ def __del__(self):
+ for button in self.button_group.buttons():
+ button.deleteLater()
+
+ if self.button_group:
+ self.button_group.deleteLater()
+ self.button_group = None
+
+ if self.uiWebAuthDialog:
+ del self.uiWebAuthDialog
+ self.uiWebAuthDialog = None
+
+ if self.scroll_area:
+ self.scroll_area.deleteLater()
+ self.scroll_area = None
+
+ def update_display(self):
+ state = self.uxRequest.state()
+ if state == QWebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount:
+ self.setupSelectAccountUI()
+ elif state == QWebEngineWebAuthUxRequest.WebAuthUxState.CollectPin:
+ self.setupCollectPinUI()
+ elif state == QWebEngineWebAuthUxRequest.WebAuthUxState.FinishTokenCollection:
+ self.setupFinishCollectTokenUI()
+ elif state == QWebEngineWebAuthUxRequest.WebAuthUxState.RequestFailed:
+ self.setupErrorUI()
+
+ self.adjustSize()
+
+ def setupSelectAccountUI(self):
+ self.uiWebAuthDialog.m_headingLabel.setText(self.tr("Choose a Passkey"))
+ self.uiWebAuthDialog.m_description.setText(self.tr("Which passkey do you want to use for ")
+ + self.uxRequest.relyingPartyId()
+ + self.tr("? "))
+ self.uiWebAuthDialog.m_pinGroupBox.setVisible(False)
+ self.uiWebAuthDialog.m_mainVerticalLayout.removeWidget(self.uiWebAuthDialog.m_pinGroupBox)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Retry).setVisible(False)
+
+ self.clearSelectAccountButtons()
+ self.scroll_area.setVisible(True)
+ self.select_account_widget.resize(self.width(), self.height())
+ userNames = self.uxRequest.userNames()
+ # Create radio buttons for each name
+ for name in userNames:
+ radioButton = QRadioButton(name)
+ self.select_account_layout.addWidget(radioButton)
+ self.button_group.addButton(radioButton)
+
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Ok"))
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Ok).setVisible(True)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Cancel).setVisible(True)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Retry).setVisible(False)
+
+ def setupFinishCollectTokenUI(self):
+
+ self.clearSelectAccountButtons()
+ self.uiWebAuthDialog.m_headingLabel.setText(self.tr("Use your security key with")
+ + self.uxRequest.relyingPartyId())
+ self.uiWebAuthDialog.m_description.setText(
+ self.tr("Touch your security key again to complete the request."))
+ self.uiWebAuthDialog.m_pinGroupBox.setVisible(False)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Ok).setVisible(False)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Retry).setVisible(False)
+ self.scroll_area.setVisible(False)
+
+ def setupCollectPinUI(self):
+
+ self.clearSelectAccountButtons()
+ self.uiWebAuthDialog.m_mainVerticalLayout.addWidget(self.uiWebAuthDialog.m_pinGroupBox)
+ self.uiWebAuthDialog.m_pinGroupBox.setVisible(True)
+ self.uiWebAuthDialog.m_confirmPinLabel.setVisible(False)
+ self.uiWebAuthDialog.m_confirmPinLineEdit.setVisible(False)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Ok).setText(self.tr("Next"))
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Ok).setVisible(True)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Cancel).setVisible(True)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Retry).setVisible(False)
+ self.scroll_area.setVisible(False)
+
+ pinRequestInfo = self.uxRequest.pinRequest()
+
+ if pinRequestInfo.reason == QWebEngineWebAuthUxRequest.PinEntryReason.Challenge:
+ self.uiWebAuthDialog.m_headingLabel.setText(self.tr("PIN Required"))
+ self.uiWebAuthDialog.m_description.setText(
+ self.tr("Enter the PIN for your security key"))
+ self.uiWebAuthDialog.m_confirmPinLabel.setVisible(False)
+ self.uiWebAuthDialog.m_confirmPinLineEdit.setVisible(False)
+ else:
+ if pinRequestInfo.reason == QWebEngineWebAuthUxRequest.PinEntryReason.Set:
+ self.uiWebAuthDialog.m_headingLabel.setText(self.tr("New PIN Required"))
+ self.uiWebAuthDialog.m_description.setText(
+ self.tr("Set new PIN for your security key"))
+ else:
+ self.uiWebAuthDialog.m_headingLabel.setText(self.tr("Change PIN Required"))
+ self.uiWebAuthDialog.m_description.setText(
+ self.tr("Change PIN for your security key"))
+
+ self.uiWebAuthDialog.m_confirmPinLabel.setVisible(True)
+ self.uiWebAuthDialog.m_confirmPinLineEdit.setVisible(True)
+
+ errorDetails = ""
+
+ if pinRequestInfo.error == QWebEngineWebAuthUxRequest.PinEntryError.InternalUvLocked:
+ errorDetails = self.tr("Internal User Verification Locked ")
+ elif pinRequestInfo.error == QWebEngineWebAuthUxRequest.PinEntryError.WrongPin:
+ errorDetails = self.tr("Wrong PIN")
+ elif pinRequestInfo.error == QWebEngineWebAuthUxRequest.PinEntryError.TooShort:
+ errorDetails = self.tr("Too Short")
+ elif pinRequestInfo.error == QWebEngineWebAuthUxRequest.PinEntryError.InvalidCharacters:
+ errorDetails = self.tr("Invalid Characters")
+ elif pinRequestInfo.error == QWebEngineWebAuthUxRequest.PinEntryError.SameAsCurrentPin:
+ errorDetails = self.tr("Same as current PIN")
+
+ if errorDetails:
+ errorDetails += f" {pinRequestInfo.remainingAttempts} attempts remaining"
+
+ self.uiWebAuthDialog.m_pinEntryErrorLabel.setText(errorDetails)
+
+ def onCancelRequest(self):
+
+ self.uxRequest.cancel()
+
+ def onAcceptRequest(self):
+
+ state = self.uxRequest.state()
+ if state == QWebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount:
+ if self.button_group.checkedButton():
+ self.uxRequest.setSelectedAccount(self.button_group.checkedButton().text())
+ elif state == QWebEngineWebAuthUxRequest.WebAuthUxState.CollectPin:
+ self.uxRequest.setPin(self.uiWebAuthDialog.m_pinLineEdit.text())
+
+ def setupErrorUI(self):
+
+ self.clearSelectAccountButtons()
+ error_description = ""
+ error_heading = self.tr("Something went wrong")
+ isVisibleRetry = False
+
+ state = self.uxRequest.requestFailureReason()
+ failure_reason = QWebEngineWebAuthUxRequest.RequestFailureReason
+
+ if state == failure_reason.Timeout:
+ error_description = self.tr("Request Timeout")
+ elif state == failure_reason.KeyNotRegistered:
+ error_description = self.tr("Key not registered")
+ elif state == failure_reason.KeyAlreadyRegistered:
+ error_description = self.tr("You already registered self device."
+ "Try again with device")
+ isVisibleRetry = True
+ elif state == failure_reason.SoftPinBlock:
+ error_description = self.tr(
+ "The security key is locked because the wrong PIN was entered too many times."
+ "To unlock it, remove and reinsert it.")
+ isVisibleRetry = True
+ elif state == failure_reason.HardPinBlock:
+ error_description = self.tr(
+ "The security key is locked because the wrong PIN was entered too many times."
+ " Yo'll need to reset the security key.")
+ elif state == failure_reason.AuthenticatorRemovedDuringPinEntry:
+ error_description = self.tr(
+ "Authenticator removed during verification. Please reinsert and try again")
+ elif state == failure_reason.AuthenticatorMissingResidentKeys:
+ error_description = self.tr("Authenticator doesn't have resident key support")
+ elif state == failure_reason.AuthenticatorMissingUserVerification:
+ error_description = self.tr("Authenticator missing user verification")
+ elif state == failure_reason.AuthenticatorMissingLargeBlob:
+ error_description = self.tr("Authenticator missing Large Blob support")
+ elif state == failure_reason.NoCommonAlgorithms:
+ error_description = self.tr("Authenticator missing Large Blob support")
+ elif state == failure_reason.StorageFull:
+ error_description = self.tr("Storage Full")
+ elif state == failure_reason.UserConsentDenied:
+ error_description = self.tr("User consent denied")
+ elif state == failure_reason.WinUserCancelled:
+ error_description = self.tr("User Cancelled Request")
+
+ self.uiWebAuthDialog.m_headingLabel.setText(error_heading)
+ self.uiWebAuthDialog.m_description.setText(error_description)
+ self.uiWebAuthDialog.m_description.adjustSize()
+ self.uiWebAuthDialog.m_pinGroupBox.setVisible(False)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Ok).setVisible(False)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Retry).setVisible(isVisibleRetry)
+ if isVisibleRetry:
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Retry).setFocus()
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Cancel).setVisible(True)
+ self.uiWebAuthDialog.buttonBox.button(QDialogButtonBox.Cancel).setText(self.tr("Close"))
+ self.scroll_area.setVisible(False)
+
+ def onRetry(self):
+ self.uxRequest.retry()
+
+ def clearSelectAccountButtons(self):
+ buttons = self.button_group.buttons()
+
+ for radio_button in buttons:
+ self.select_account_layout.removeWidget(radio_button)
+ self.button_group.removeButton(radio_button)
+ radio_button.deleteLater()
diff --git a/examples/webenginewidgets/simplebrowser/webauthdialog.ui b/examples/webenginewidgets/simplebrowser/webauthdialog.ui
new file mode 100644
index 000000000..c8a0456d6
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webauthdialog.ui
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WebAuthDialog</class>
+ <widget class="QDialog" name="WebAuthDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>563</width>
+ <height>397</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>320</y>
+ <width>471</width>
+ <height>32</height>
+ </rect>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Retry</set>
+ </property>
+ </widget>
+ <widget class="QLabel" name="m_headingLabel">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>20</y>
+ <width>321</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Heading</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" name="m_description">
+ <property name="geometry">
+ <rect>
+ <x>30</x>
+ <y>60</y>
+ <width>491</width>
+ <height>31</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QWidget" name="layoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>100</y>
+ <width>471</width>
+ <height>171</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="m_mainVerticalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="m_pinGroupBox">
+ <property name="title">
+ <string/>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <widget class="QLabel" name="m_pinLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>58</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PIN</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="m_pinLineEdit">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>20</y>
+ <width>113</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="m_confirmPinLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>50</y>
+ <width>81</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Confirm PIN</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" name="m_confirmPinLineEdit">
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>50</y>
+ <width>113</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLabel" name="m_pinEntryErrorLabel">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>80</y>
+ <width>441</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.py b/examples/webenginewidgets/simplebrowser/webpopupwindow.py
index fd82ed9f2..5b5ed1733 100644
--- a/examples/webenginewidgets/simplebrowser/webpopupwindow.py
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.py
@@ -13,7 +13,6 @@ class WebPopupWindow(QWidget):
def __init__(self, view, profile, parent=None):
super().__init__(parent, Qt.Window)
- self.m_urlLineEdit = QLineEdit(self)
self._url_line_edit = QLineEdit()
self._fav_action = QAction(self)
self._view = view
diff --git a/examples/webenginewidgets/simplebrowser/webview.py b/examples/webenginewidgets/simplebrowser/webview.py
index c7e577176..4b106acb2 100644
--- a/examples/webenginewidgets/simplebrowser/webview.py
+++ b/examples/webenginewidgets/simplebrowser/webview.py
@@ -5,21 +5,24 @@ from __future__ import annotations
from functools import partial
from PySide6.QtWebEngineCore import (QWebEngineFileSystemAccessRequest,
- QWebEnginePage)
+ QWebEnginePage,
+ QWebEngineWebAuthUxRequest)
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtWidgets import QDialog, QMessageBox, QStyle
from PySide6.QtGui import QIcon
from PySide6.QtNetwork import QAuthenticator
-from PySide6.QtCore import QTimer, Signal, Slot
+from PySide6.QtCore import QTimer, Signal, Slot, Qt
from webpage import WebPage
from webpopupwindow import WebPopupWindow
from ui_passworddialog import Ui_PasswordDialog
from ui_certificateerrordialog import Ui_CertificateErrorDialog
+from webauthdialog import WebAuthDialog
def question_for_feature(feature):
+
if feature == QWebEnginePage.Geolocation:
return "Allow %1 to access your location information?"
if feature == QWebEnginePage.MediaAudioCapture:
@@ -59,6 +62,7 @@ class WebView(QWebEngineView):
self._loading_icon = QIcon.fromTheme(QIcon.ThemeIcon.ViewRefresh,
QIcon(":view-refresh.png"))
self._default_icon = QIcon(":text-html.png")
+ self.auth_dialog = None
@Slot()
def _load_started(self):
@@ -105,6 +109,7 @@ class WebView(QWebEngineView):
self.handle_proxy_authentication_required)
old_page.registerProtocolHandlerRequested.disconnect(
self.handle_register_protocol_handler_requested)
+ old_page.webAuthUxRequested.disconnect(self.handle_web_auth_ux_requested)
old_page.fileSystemAccessRequested.disconnect(self.handle_file_system_access_requested)
self.create_web_action_trigger(page, QWebEnginePage.WebAction.Forward)
@@ -118,6 +123,7 @@ class WebView(QWebEngineView):
page.proxyAuthenticationRequired.connect(self.handle_proxy_authentication_required)
page.registerProtocolHandlerRequested.connect(
self.handle_register_protocol_handler_requested)
+ page.webAuthUxRequested.connect(self.handle_web_auth_ux_requested)
page.fileSystemAccessRequested.connect(self.handle_file_system_access_requested)
def load_progress(self):
@@ -265,6 +271,28 @@ class WebView(QWebEngineView):
# Set authenticator null if dialog is cancelled
auth = QAuthenticator()
+ def handle_web_auth_ux_requested(self, request):
+ if self.auth_dialog:
+ self.auth_dialog.deleteLater()
+
+ self.auth_dialog = WebAuthDialog(request, self.window())
+ self.auth_dialog.setModal(False)
+ self.auth_dialog.setWindowFlags(self.auth_dialog.windowFlags()
+ & ~Qt.WindowContextHelpButtonHint)
+
+ request.stateChanged.connect(self.on_state_changed)
+ self.auth_dialog.show()
+
+ def on_state_changed(self, state):
+ if state in (QWebEngineWebAuthUxRequest.WebAuthUxState.Completed,
+ QWebEngineWebAuthUxRequest.WebAuthUxState.Cancelled):
+ if self.auth_dialog:
+ self.auth_dialog.deleteLater()
+ self.auth_dialog = None
+ else:
+ if self.auth_dialog:
+ self.auth_dialog.update_display()
+
def handle_register_protocol_handler_requested(self, request):
host = request.origin().host()
m = f"Allow {host} to open all {request.scheme()} links?"