You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PyQt5中为QWebEngine自定义右键菜单添加"在新标签页打开链接"功能

实现PyQt QWebEngineView右键菜单添加"在新标签页打开"链接功能

先拆解你看到的那段C++代码逻辑

这段代码是Qt官方示例里的右键菜单自定义逻辑,核心是基于系统自带菜单做扩展,我一步步给你解释:

  1. contextMenuEvent(QContextMenuEvent *event):这是Qt控件的右键事件回调函数,用户右键点击网页时会自动触发它。
  2. QMenu *menu = page()->createStandardContextMenu():调用网页页面(QWebEnginePage)的方法,生成浏览器默认的右键菜单,里面包含复制、粘贴、查看源码等基础功能,针对链接还会有默认的"在当前窗口打开"选项。
  3. 查找"在当前窗口打开"的动作:通过menu->actions()获取菜单里的所有动作列表,用std::find定位系统内置的OpenLinkInThisWindow动作——也就是右键点击链接时默认的"在当前窗口打开"选项。
  4. 修改文本并插入新动作:如果找到这个动作,先把它的文本改成"Open Link in This Tab"(更贴合标签页浏览器的表述),然后在它后面插入两个系统自带动作:OpenLinkInNewWindow(新窗口打开链接)和OpenLinkInNewTab(新标签页打开链接)。
  5. 弹出菜单:最后把修改后的菜单显示在用户右键点击的全局位置(event->globalPos()是鼠标的全局坐标)。

对应的PyQt完整实现代码

下面是可以直接运行的PyQt5/PyQt6代码,我加了详细注释,帮你快速理解:

要注意:PyQt逻辑和C++基本一致,但语法有差异(比如没有std::find,我们用循环查找动作);另外OpenLinkInNewTab动作默认不会自动创建新标签页,需要我们自己实现标签页的添加逻辑。

完整代码(以PyQt5为例,PyQt6仅需修改导入路径)

import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTabWidget, 
                             QWebEngineView, QMenu)
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from PyQt5.QtGui import QContextMenuEvent

class MyWebView(QWebEngineView):
    def __init__(self, parent=None):
        super().__init__(parent)
        # 绑定新标签页请求的信号,处理创建新标签页的逻辑
        self.page().linkAboutToOpen.connect(self.handle_new_tab)

    def contextMenuEvent(self, event: QContextMenuEvent):
        # 1. 创建系统默认右键菜单
        menu = self.page().createStandardContextMenu()
        actions = menu.actions()

        # 2. 查找"在当前窗口打开"的动作(对应C++的OpenLinkInThisWindow)
        target_action = None
        for action in actions:
            # 通过动作的objectName匹配,PyQt里系统动作的objectName是固定的
            if action.objectName() == "action_openLinkInThisWindow":
                target_action = action
                break

        if target_action:
            # 3. 修改当前动作的文本为"在当前标签页打开"
            target_action.setText("在当前标签页打开")
            # 获取当前动作在菜单中的索引,方便插入新动作
            action_index = actions.index(target_action)
            # 4. 获取要插入的系统动作:新窗口打开、新标签页打开
            open_in_new_window = self.page().action(QWebEnginePage.OpenLinkInNewWindow)
            open_in_new_window.setText("在新窗口打开")
            open_in_new_tab = self.page().action(QWebEnginePage.OpenLinkInNewTab)
            open_in_new_tab.setText("在新标签页打开")

            # 5. 在目标动作的下一个位置插入新动作
            next_action = actions[action_index + 1] if action_index + 1 < len(actions) else None
            menu.insertAction(next_action, open_in_new_tab)
            menu.insertAction(open_in_new_tab, open_in_new_window)

        # 6. 弹出菜单
        menu.exec_(event.globalPos())

    def handle_new_tab(self, url):
        # 这里处理新标签页的创建逻辑,根据你的UI结构调整父控件层级
        main_window = self.parent().parent()
        if isinstance(main_window, QMainWindow) and isinstance(main_window.centralWidget(), QTabWidget):
            new_webview = MyWebView()
            new_webview.load(url)
            tab_widget = main_window.centralWidget()
            tab_widget.addTab(new_webview, "新标签页")
            tab_widget.setCurrentWidget(new_webview)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("自定义右键菜单浏览器")
        self.setGeometry(100, 100, 1200, 800)

        # 创建标签页容器
        self.tab_widget = QTabWidget()
        self.setCentralWidget(self.tab_widget)

        # 添加初始标签页
        initial_webview = MyWebView()
        initial_webview.load("https://www.baidu.com")
        self.tab_widget.addTab(initial_webview, "首页")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

关键说明

  1. 动作匹配:PyQt中系统内置动作的objectName是固定的,比如action_openLinkInThisWindow对应C++的OpenLinkInThisWindow,我们通过这个来定位目标动作。
  2. 新标签页处理linkAboutToOpen信号会在点击"在新标签页打开"时触发,我们需要在这个信号的处理函数里创建新的QWebEngineView,并添加到主窗口的QTabWidget中。
  3. PyQt6适配:如果用PyQt6,只需要把导入路径中的PyQt5改成PyQt6,同时QContextMenuEvent的导入路径改为from PyQt6.QtGui import QContextMenuEvent,其他逻辑完全一致。

内容的提问来源于stack exchange,提问作者Maxwe11

火山引擎 最新活动