You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python在PyQt6/PySide6中调用Windows资源管理器右键菜单?

在PyQt6/PySide6 TreeView中调用Windows资源管理器右键菜单

实现思路

核心是通过Windows Shell API调用系统原生上下文菜单,步骤分为:捕获TreeView右键点击事件、获取目标文件/文件夹路径、调用系统接口弹出菜单。

所需依赖

先安装pywin32库:

pip install pywin32

完整示例代码

PyQt6版本

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QTreeView, QFileSystemModel
from PyQt6.QtCore import Qt, QPoint
import win32api
import win32con
import win32gui
import win32shell
from win32com.shell import shell, shellcon

class FileTreeWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("资源管理器右键菜单示例")
        self.resize(800, 600)

        # 初始化文件系统模型与TreeView
        self.model = QFileSystemModel()
        self.model.setRootPath("C:/")
        self.tree_view = QTreeView(self)
        self.tree_view.setModel(self.model)
        self.tree_view.setRootIndex(self.model.index("C:/"))
        # 开启自定义右键菜单
        self.tree_view.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        # 绑定右键点击信号到处理函数
        self.tree_view.customContextMenuRequested.connect(self.show_windows_context_menu)

        self.setCentralWidget(self.tree_view)

    def show_windows_context_menu(self, pos: QPoint):
        # 获取点击位置对应的TreeView索引
        index = self.tree_view.indexAt(pos)
        if not index.isValid():
            return

        # 获取目标文件/文件夹的绝对路径
        file_path = self.model.filePath(index)
        if not file_path:
            return

        # 转换为屏幕坐标(Windows API使用屏幕坐标系)
        global_pos = self.tree_view.mapToGlobal(pos)

        # 调用Windows Shell API弹出系统菜单
        try:
            # 将文件路径转换为Shell识别的PIDL(项目标识符列表)
            pidl = shell.SHILCreateFromPath(file_path, 0)[0]
            # 获取桌面窗口作为菜单父窗口
            hwnd = win32gui.GetDesktopWindow()
            # 创建Shell文件夹视图对象
            cm = shell.SHCreateShellFolderView(hwnd, pidl)
            # 获取对应路径的上下文菜单
            menu = cm.GetMenu()
            # 在指定位置弹出菜单并获取选中的命令ID
            cmd = win32gui.TrackPopupMenuEx(
                menu,
                win32con.TPM_RETURNCMD,
                global_pos.x(),
                global_pos.y(),
                hwnd,
                None
            )
            # 执行选中的菜单命令
            if cmd:
                cm.InvokeCommand(cmd, 0)
        except Exception as e:
            print(f"菜单调用失败: {e}")

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

PySide6版本

仅替换PyQt6的导入模块,其余代码完全一致:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QTreeView, QFileSystemModel
from PySide6.QtCore import Qt, QPoint
# 其余导入及代码与PyQt6版本相同

关键逻辑说明

  • customContextMenuRequested:TreeView的右键点击信号,触发菜单弹出流程
  • shell.SHILCreateFromPath:将文件路径转换为Shell可识别的PIDL,是调用系统菜单的核心前提
  • SHCreateShellFolderView:创建对应路径的Shell视图对象,用于获取原生上下文菜单
  • TrackPopupMenuEx:在指定位置弹出菜单,InvokeCommand执行用户选中的菜单命令

注意事项

  • 仅支持Windows系统,依赖Windows专属API
  • 若出现pywin32导入错误,可尝试升级库:pip install --upgrade pywin32
  • 针对特殊权限文件、网络路径,可能需要额外处理权限验证逻辑

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:53:15