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属性配置和样式表精准定位两个方面调整,具体步骤如下:
- 设置Action的菜单弹出模式
默认带菜单的QAction会拆成两个按钮(主按钮+下拉箭头按钮),你需要把它改成点击直接弹出菜单:
self.t_path_output_act.setMenu(self.window_context_menu) # 新增这行:设置点击Action直接弹出菜单,不再显示拆分按钮 self.t_path_output_act.setPopupMode(QToolButton.InstantPopup)
- 用样式表彻底隐藏菜单指示器
之前的样式表没精准定位到QToolBar里的QToolButton,得给目标按钮指定正确的样式。直接给QToolBar设置全局样式最省事:
self.main_toolbar.setStyleSheet(""" QToolBar QToolButton::menu-indicator { image: none; width: 0px; height: 0px; } """)
这段样式会隐藏QToolBar内所有带菜单按钮的指示器,完全去掉箭头。
- 修改后的关键代码片段
在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
相关产品推荐
相关产品推荐

