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

Qt中QAction绑定QIcon后复选框不可见,如何同时显示两者?

How to Display Both Icon and Checkmark for Checkable QAction in QMenu?

Absolutely! You can definitely show both the icon and checkmark for your checkable QActions in a QMenu. The problem you're running into is that Qt's default style hides the check indicator when an action has an icon—instead, it typically uses the icon's state to signal if the action is checked. But if you want both elements visible, here are two reliable ways to make it happen:

Method 1: Use QWidgetAction for Custom Menu Items

This approach lets you build a custom widget that includes both the icon and a checkbox, giving you full control over the layout and behavior.

from PyQt5 import QtWidgets, QtGui, QtCore
import sys

class window21(QtWidgets.QMainWindow):
    def __init__(self):
        super(window21,self).__init__()
        
        # Helper function to create checkable actions with icon and visible checkbox
        def create_checkable_action(text, icon_path=None):
            widget_action = QtWidgets.QWidgetAction(self)
            # Set up a horizontal layout for the custom widget
            layout = QtWidgets.QHBoxLayout()
            layout.setContentsMargins(4, 2, 4, 2)
            layout.setSpacing(8)
            
            # Add checkbox with the action text
            checkbox = QtWidgets.QCheckBox(text)
            checkbox.setCheckable(True)
            
            # Add icon if a path is provided
            if icon_path:
                icon_label = QtWidgets.QLabel()
                icon_label.setPixmap(QtGui.QPixmap(icon_path).scaled(16, 16, QtCore.Qt.KeepAspectRatio))
                layout.addWidget(icon_label)
            
            layout.addWidget(checkbox)
            
            # Wrap the layout in a container widget
            container = QtWidgets.QWidget()
            container.setLayout(layout)
            widget_action.setDefaultWidget(container)
            
            # Sync checkbox state with the action's checked state
            def sync_action_state(state):
                widget_action.setChecked(state == QtCore.Qt.Checked)
            checkbox.stateChanged.connect(sync_action_state)
            
            return widget_action

        # Create your actions using the helper function
        self.newAction = create_checkable_action("&New", ":/im/new.png")
        self.openAction = create_checkable_action("&Open")
        self.printAction = create_checkable_action("&Print")
        self.quitAction = create_checkable_action("&Quit")
        self.saveAction = create_checkable_action("&Save")

        self.groupMenu = QtWidgets.QMenu("nested menu", self)
        self.groupAction = QtWidgets.QActionGroup(self)
        
        myMenu = self.menuBar()
        file = myMenu.addMenu("&File")
        
        # Add custom actions to the File menu
        file.addAction(self.newAction)
        file.addAction(self.openAction)
        file.addAction(self.printAction)
        
        # Set up exclusive action group for nested menu
        self.groupAction.addAction(self.quitAction)
        self.groupAction.addAction(self.saveAction)
        self.groupAction.setExclusive(True)
        
        # Sync action group selection with checkboxes
        def sync_group_selection(selected_action):
            for action in self.groupAction.actions():
                checkbox = action.defaultWidget().findChild(QtWidgets.QCheckBox)
                checkbox.setChecked(action == selected_action)
        self.groupAction.triggered.connect(sync_group_selection)
        
        for j in self.groupAction.actions():
            self.groupMenu.addAction(j)
        
        file.addMenu(self.groupMenu)
        self.show()

app = QtWidgets.QApplication([])
ex = window21()
sys.exit(app.exec_())

Method 2: Tweak the QMenu's Stylesheet

If you prefer a simpler fix without custom widgets, you can force the check indicator to appear even when an action has an icon by adjusting the menu's stylesheet.

Add this line right after creating your file menu:

file.setStyleSheet("""
    QMenu::item {
        padding-left: 28px; /* Add space to the left for the check indicator */
    }
    QMenu::indicator {
        left: 6px;
        width: 16px;
        height: 16px;
        /* Optional: Customize the indicator appearance */
        /* image: url(:/check-icon.png); */
    }
""")

This stylesheet adjusts the padding to make room for the checkmark and ensures the indicator is visible regardless of whether the action has an icon. Note that stylesheet behavior can vary slightly across platforms, but this works consistently for most desktop environments.

Why This Happens

Qt's default styles (like Fusion, Windows, or macOS) hide the check indicator when an action has an icon because they assume you'll use a different icon state (e.g., a highlighted or checked version of the icon) to indicate the action's status. But if you want both the icon and the checkmark visible, the methods above will solve that problem.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:01:33