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

PyQt6:移除带弹出菜单的QToolBar动作箭头并合并按钮

问题

我正在开发一款文件管理器,需要对QToolBar中关联QMenu的QAction实现以下效果:

  • 完全移除箭头
  • 将附带的小按钮与QToolBar上的QAction合并
  • 让该QAction直接作为下拉菜单使用

我已尝试以下样式表设置,但未解决问题:

  • setStyleSheet("::menu-arrow { image: none; }")
  • setStyleSheet("::icon { display: none; }")
  • setStyleSheet("::menu-indicator { image: none; }")

组件层级为:QToolBar --> QAction --> QMenu,以下是我的实现代码:

def setUpMainWindow(self):
    self.main_toolbar = QToolBar()
    self.setUpToolBar()

    self.addToolBar(self.main_toolbar)
    self.addToolBarBreak()
    ...................
    ..............
    .........


def setUpToolBar(self):
    self.main_toolbar.setFixedHeight(45)
    self.main_toolbar.setMovable(False)
    self.main_toolbar.setContextMenuPolicy(Qt.ContextMenuPolicy.DefaultContextMenu)
    self.main_toolbar.setIconSize(QSize(25, 25))
    self.main_toolbar.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)

    t_back_i = QIcon(QPixmap("icons/back.png"))
    self.t_back_act = QAction(t_back_i, "")
    self.t_back_act.setToolTip("Back")
    self.t_back_act.triggered.connect(self.directory_back_process)

    t_fwrd_i = QIcon(QPixmap("icons/forward.png"))
    self.t_frwd_act = QAction(t_fwrd_i, "")
    self.t_frwd_act.setEnabled(False)
    self.t_frwd_act.triggered.connect(self.directory_forward_process)

    t_path_output_i = QIcon(QPixmap("icons/vert-menu.png"))
    self.t_path_output_act = QAction(t_path_output_i, "")
    #self.t_path_output_act.setFixedSize(30,30)
    self.t_path_output_act.setMenu(self.window_context_menu)

    t_srch_i = QIcon(QPixmap("icons/search.png"))
    self.t_srch_act = QAction(t_srch_i, "")

    self.dirPath_h_box = QHBoxLayout()
    self.dirPath_h_box.setContentsMargins(10, 0, 10, 0)
    self.dirPath_h_box.setSpacing(5)
    self.dirPath_h_box.setAlignment(Qt.AlignmentFlag.AlignLeft)



    pathOutput_widget = QWidget()
    pathOutput_widget.setLayout(self.dirPath_h_box)
    self.pathOutput = QScrollArea()
    self.pathOutput.setFixedSize(415,30)
    self.pathOutput.setObjectName("tbFrame")

    self.pathOutput.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
    self.pathOutput.horizontalScrollBar().setStyleSheet("QScrollBar {height:0px}")
    self.pathOutput.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
    self.pathOutput.setWidgetResizable(True)
    self.pathOutput.setWidget(pathOutput_widget)



    spacer_1 = QWidget()
    spacer_1.setFixedWidth(5)
    spacer_2 = QWidget()
    spacer_2.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
    spacer_3 = QWidget()
    spacer_3.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)

    self.main_toolbar.addWidget(spacer_1)
    self.main_toolbar.addAction(self.t_back_act)
    self.main_toolbar.addAction(self.t_frwd_act)
    self.main_toolbar.addWidget(spacer_2)
    self.main_toolbar.addWidget(self.pathOutput)
    self.main_toolbar.addAction(self.t_path_output_act)
    self.main_toolbar.addAction(self.t_srch_act)
    self.main_toolbar.addWidget(spacer_3)


    self.displayPath(QDir.homePath())

def setUpContextMenu(self):
    self.window_context_menu = QMenu()
    self.window_context_menu.setObjectName("idk")
    self.window_context_menu.addAction(self.copy_directory_act)
    #self.window_context_menu.addAction(self.paste_directory_act)
    self.window_context_menu.addAction(self.new_directory_act)
    self.window_context_menu.addAction(self.delete_directory_act)
    #self.window_context_menu.addAction(self.select_all_act)


 def setUpActions(self):
    self.copy_directory_act = QAction("Copy")
    self.copy_directory_act.triggered.connect(self.copy_directory)
    self.paste_directory_act = QAction("Paste")
    #self.paste_directory_act.triggered.connect(self.paste_directory)
    self.new_directory_act = QAction("New Folder")
    self.new_directory_act.triggered.connect(self.new_directory)
    self.delete_directory_act = QAction("Delete")
    self.delete_directory_act.triggered.connect(self.delete_directory)
    self.select_all_act = QAction("Select All")
    #self.select_all_act.triggered.connect(self.select_all)

*注:setUpContextMenu方法并非用于QToolBar的上下文菜单。

解决方案

要实现你的需求,得从Action属性配置和样式表精准定位两个方面调整,具体步骤如下:

  1. 设置Action的菜单弹出模式
    默认带菜单的QAction会拆成两个按钮(主按钮+下拉箭头按钮),你需要把它改成点击直接弹出菜单:
self.t_path_output_act.setMenu(self.window_context_menu)
# 新增这行:设置点击Action直接弹出菜单,不再显示拆分按钮
self.t_path_output_act.setPopupMode(QToolButton.InstantPopup)
  1. 用样式表彻底隐藏菜单指示器
    之前的样式表没精准定位到QToolBar里的QToolButton,得给目标按钮指定正确的样式。直接给QToolBar设置全局样式最省事:
self.main_toolbar.setStyleSheet("""
    QToolBar QToolButton::menu-indicator {
        image: none;
        width: 0px;
        height: 0px;
    }
""")

这段样式会隐藏QToolBar内所有带菜单按钮的指示器,完全去掉箭头。

  1. 修改后的关键代码片段
    在setUpToolBar方法里,更新t_path_output_act的配置:
t_path_output_i = QIcon(QPixmap("icons/vert-menu.png"))
self.t_path_output_act = QAction(t_path_output_i, "")
self.t_path_output_act.setMenu(self.window_context_menu)
# 新增:设置弹出模式为点击直接弹出菜单
self.t_path_output_act.setPopupMode(QToolButton.InstantPopup)

然后在setUpToolBar方法末尾添加样式表设置:

# 隐藏菜单指示器
self.main_toolbar.setStyleSheet("""
    QToolBar QToolButton::menu-indicator {
        image: none;
        width: 0;
        height: 0;
    }
""")

这样修改后,点击这个Action按钮会直接弹出菜单,看不到箭头,按钮也不会拆分,完全符合你的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 00:14:52