我正在尝试制作一个包含 QWebEngineView 的窗口。现在我希望浏览器能够处理创建窗口或 _blank 类型的触发器,或者专门在需要时在新窗口中打开 URL。在下面的代码中,当浏览器需要创建一个窗口时,会调用 createwindow(),但不会打开窗口。请帮助我在以下情况下需要时通过浏览器打开新窗口的正确方法。
import json
import sys
import os
import time
import json
import sys
import platform
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtWebEngineWidgets import QWebEngineSettings as QWebSettings
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import QUrl
from main_dash import Ui_MainWindow
class MainDashWindow(QMainWindow):
socketSignal = QtCore.pyqtSignal(object) # must be defined in class level
def __init__(self):
QMainWindow.__init__(self)
self.ui = Ui_MainWindow()
# self.ui.setupUi(self)
# ui = Ui_MainWindow()
self.isMax = 0
self.ui.setupUi(self)
def re_setup(self):
self.page = WebEnginePage2()
self.page.Notifications = True
self.ui.full_content_container.hide()
self.page.createWindow = True
self.page.settings().setAttribute(QWebSettings.JavascriptEnabled, True)
self.page.settings().setAttribute(QWebSettings.JavascriptCanOpenWindows, True)
self.page.settings().setAttribute(
QWebSettings.JavascriptCanAccessClipboard, True)
# self.full_content_container is the webengineview in the mainUi file
self.ui.full_content_container.setPage(self.page)
# self.ui.full_content_container.setContextMenuPolicy(Qt.NoContextMenu)
url6 = "...../icons_nec/ui/index.html"
self.ui.full_content_container.setUrl(QtCore.QUrl(url6))
self.ui.full_content_container.loadFinished.connect(
self.on_load_finished)
########################################################################
self.show()
## ==> END ##
def get_path(self, filename):
if hasattr(sys, "_MEIPASS"):
return f'{os.path.join(sys._MEIPASS, filename)}'
else:
return f'{filename}'
def on_load_finished(self):
self.ui.full_content_container.show()
class WebEnginePage2(QWebEnginePage):
def __init__(self, *args, **kwargs):
QWebEnginePage.__init__(self, *args, **kwargs)
self.featurePermissionRequested.connect(
self.onFeaturePermissionRequested)
def onFeaturePermissionRequested(self, url, feature):
self.setFeaturePermission(
url, feature, QWebEnginePage.PermissionGrantedByUser)
def createWindow(self,
wintype: QWebEnginePage.WebWindowType) -> QWebEngineView:
"""Called by Qt when a page wants to create a new tab or window.
In case the user wants to open a resource in a new tab, we use the
createWindow handling of the main page to achieve that.
See WebEngineView.createWindow for details.
"""
return self.page().inspectedPage().view().createWindow(wintype)
# Store external windows.
external_windows = []
def acceptNavigationRequest(self, url, _type, isMainFrame):
print("in navigation")
if _type == QWebEnginePage.NavigationTypeLinkClicked:
w = QWebEngineView()
w.setUrl(url)
w.show()
print("link detected")
# Keep reference to external window, so it isn't cleared up.
self.external_windows.append(w)
return False
# QDesktopServices.openUrl(url)
# elif _type == QWebEnginePage.NavigationType
return super().acceptNavigationRequest(url, _type, isMainFrame)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainDashWindow()
window.re_setup()
sys.exit(app.exec_())
这是上面正在导入的 Ui_MainWindow 文件。如果网站需要,我需要在这种情况下弄清楚如何实现 createWindow() 。
from PyQt5 import QtWebEngineWidgets
import all_icons_rc
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 720)
MainWindow.setMinimumSize(QtCore.QSize(1280, 720))
MainWindow.setMaximumSize(QtCore.QSize(1920, 1080))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_2.setSpacing(0)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.Header = QtWidgets.QFrame(self.centralwidget)
self.Header.setMinimumSize(QtCore.QSize(0, 40))
self.Header.setMaximumSize(QtCore.QSize(16777215, 50))
self.Header.setStyleSheet("background-color: rgb(33, 37, 41);")
self.Header.setFrameShape(QtWidgets.QFrame.NoFrame)
self.Header.setFrameShadow(QtWidgets.QFrame.Raised)
self.Header.setObjectName("Header")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.Header)
self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_4.setSpacing(0)
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.frame_2 = QtWidgets.QFrame(self.Header)
self.frame_2.setStyleSheet("")
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.horizontalLayout_4.addWidget(self.frame_2)
self.frame = QtWidgets.QFrame(self.Header)
self.frame.setMaximumSize(QtCore.QSize(150, 16777215))
self.frame.setStyleSheet("/*background-color: rgb(85, 255, 0);*/")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
self.horizontalLayout.setSpacing(15)
self.horizontalLayout.setObjectName("horizontalLayout")
self.minimize_btn = QtWidgets.QPushButton(self.frame)
self.minimize_btn.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(
":/icons/Icons/icons8_macos_minimize_50px.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.minimize_btn.setIcon(icon)
self.minimize_btn.setIconSize(QtCore.QSize(30, 30))
self.minimize_btn.setFlat(True)
self.minimize_btn.setObjectName("minimize_btn")
self.horizontalLayout.addWidget(self.minimize_btn)
self.maximize_btn = QtWidgets.QPushButton(self.frame)
self.maximize_btn.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(
":/icons/Icons/icons8_maximize_window_50px.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.maximize_btn.setIcon(icon1)
self.maximize_btn.setIconSize(QtCore.QSize(30, 30))
self.maximize_btn.setFlat(True)
self.maximize_btn.setObjectName("maximize_btn")
self.horizontalLayout.addWidget(self.maximize_btn)
self.close_btn = QtWidgets.QPushButton(self.frame)
self.close_btn.setText("")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(
":/icons/Icons/icons8_Close_50px_2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.close_btn.setIcon(icon2)
self.close_btn.setIconSize(QtCore.QSize(30, 30))
self.close_btn.setFlat(True)
self.close_btn.setObjectName("close_btn")
self.horizontalLayout.addWidget(self.close_btn)
self.horizontalLayout_4.addWidget(self.frame)
self.verticalLayout_2.addWidget(self.Header)
self.body = QtWidgets.QFrame(self.centralwidget)
self.body.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.body.setFrameShadow(QtWidgets.QFrame.Raised)
self.body.setLineWidth(0)
self.body.setObjectName("body")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.body)
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_3.setSpacing(0)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.full_content_container = QtWebEngineWidgets.QWebEngineView(
self.body)#<----This is webengineview
self.full_content_container.setStyleSheet("background-color: rgb(85, 255, 255);\n"
"border:none;")
self.full_content_container.setObjectName("full_content_container")
self.verticalLayout_3.addWidget(self.full_content_container)
self.verticalLayout_2.addWidget(self.body)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
现在,只需忽略图标。
正在 webengineview 中加载以进行测试的 index.html 文件片段
<!DOCTYPE html>
<html>
<body>
<h1>The a target attribute</h1>
<p>Open link in a new window or tab: <a href="https://pathor.in" target="_blank">Visit PathOr!</a></p>
</body>
</html>