【问题标题】:PyQt - Make QAction checkable even if it is disabledPyQt - 使 QAction 可检查,即使它被禁用
【发布时间】:2017-05-03 21:38:16
【问题描述】:

我想要一个行为稍有改变的 QAction。我希望 QAction 仅在检查时发出信号,并且我希望其复选框始终可检查,即使 QAction 已被禁用。例如,如果您将 QAction 设置为 setEnabled(False),则无法单击 QAction 或选中/取消选中它。我喜欢它不能再被点击,但不喜欢我不能切换 QAction 中的复选框。是否可以对其进行修改以获得我正在寻找的内容?

我在下面附上了一个示例文件。目标是制定一些解决方案,其中 QAction 设置为禁用 (setEnabled(False)) 但用户仍然可以选中/取消选中它。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''An example file with a QAction that stays checkable.'''

# IMPORT STANDARD LIBRARIES
import sys

# IMPORT THIRD-PARTY LIBRARIES
from Qt import QtWidgets
from Qt import QtCore


class AlwaysOpenAction(QtWidgets.QAction):
    def __init__(self, *args, **kwargs):
        super(AlwaysOpenAction, self).__init__(*args, **kwargs)
        self.toggled.connect(self.printout)

    def printout(self):
        if self.isChecked():
            print('Checkbox was checked')


class WindowTest(QtWidgets.QWidget):

    '''A basic window.'''

    def __init__(self, parent=None):
        '''Init the window.'''
        super(WindowTest, self).__init__(parent=parent)
        self.setLayout(QtWidgets.QHBoxLayout())
        self.menubar = QtWidgets.QMenuBar(parent=self)
        self.menu = self.menubar.addMenu('Some menu')

        action = AlwaysOpenAction('something', self.menu)
        action.setCheckable(True)
        action.setEnabled(False)

        self.menu.addAction(action)
        self.layout().addWidget(self.menubar)
        self.resize(500, 400)


def main():
    '''Do the window test.'''
    qapp = QtWidgets.QApplication(sys.argv)
    window = WindowTest()
    window.show()
    sys.exit(qapp.exec_())


if __name__ == '__main__':
    main()

【问题讨论】:

  • 我可以知道它有什么用吗?也许我们可以为您的问题找出不同的解决方案,因为这听起来不像 QActions 的预期行为。
  • 是的,当然。基本上,我有一个应用程序,它有一个包含许多工具的菜单。有些工具有依赖关系,有些则没有。一些工具具有自动设置自己的依赖项,因此工具本身不需要每次都像其他工具一样按下才能运行。他们只需要加载/卸载一次。在他们没有任何运行时行为的情况下,我想要一种方法来打开/关闭依赖项,而无需实际运行 QAction 的单击功能,但也向用户显示(通常只是将其变灰或制作它不可点击)
  • 你可以更好地解释我,你的问题很混乱。
  • 您希望QAction 向什么样的事件发出信号?
  • 我将问题编辑为更清楚。不是信号的问题。默认情况下,我需要与 QAction 不同的行为。如果 QAction 被禁用,您不能单击它或选中/取消选中它的状态。即使它被禁用,我仍然需要能够选中/取消选中它

标签: python pyqt


【解决方案1】:

因为您仍然希望能够在 QAction 中单击以选中和取消选中,我认为没有必要禁用 QAction。相反,你可以改变它的外观。 你试过弄乱样式表吗?

只需尝试在您的代码中添加这个简单的行:

self.menu.setStyleSheet("""color: gray;""")

所以我在这里想说的是,您可以根据自己的意愿更改 qaction 的样式。

您也可以尝试更详细和更具体的方法,上面的行会将菜单中的每个文本都更改为灰色,您可以指定要更改字体颜色的对象类型等等,例如:

self.menu.setStyleSheet("""QPushButton{background-color: red}""")

等等……

您可以尝试一些其他方法来实现您想要的,有时我们只是卡在某件事上,但还有其他方法可以做到这一点。快速查看我修改的这段代码,它与您想要的类似,我认为“)

'''An example file with a QAction that stays checkable.'''

# IMPORT STANDARD LIBRARIES
import sys

# IMPORT THIRD-PARTY LIBRARIES
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QCheckBox
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QMenuBar
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QWidgetAction



class CheckBox(QCheckBox):

    def __init__(self, name):
        super(CheckBox, self).__init__()
        self.update_color()
        self.setText(name)

    def mousePressEvent(self, event):
        self.update_color()
        super(CheckBox, self).mousePressEvent(event)

    def update_color(self):
        if self.isChecked():
            self.setStyleSheet("color: gray;")
        else:
            self.setStyleSheet("")

class WindowTest(QWidget):

    '''A basic window.'''

    def __init__(self, parent=None):
        '''Init the window.'''
        super(WindowTest, self).__init__(parent=parent)
        self.setLayout(QHBoxLayout())
        self.menubar = QMenuBar(parent=self)
        self.menu = self.menubar.addMenu('Some menu')
        self.menu.setContentsMargins(10,10,10,10)
        self.widget_action = QWidgetAction(self)
        self.button = CheckBox("some")
        self.button.setCheckable(True)
        self.button.setFixedSize(100, 20)
        self.widget_action.setDefaultWidget(self.button)
        self.menu.addAction(self.widget_action)
        self.setFixedSize(500,200)


def main():
    '''Do the window test.'''
    qapp = QApplication(sys.argv)
    window = WindowTest()
    window.show()
    sys.exit(qapp.exec_())


if __name__ == '__main__':
    main()

自从我给你的样式表的第一个示例以来,我给你的样式表有一个缺陷,因为 QAction 不是一个小部件,所以我不能真正更改它的样式表(它没有)所以我不得不更改菜单样式表什么会影响其他所有人。第二个示例使用 QCheckBox 这是一个小部件,因此我可以专门更改其样式表,并且我可以更好地控制菜单中的每个项目:D

【讨论】:

  • QSS 中有没有办法禁用小部件的点击功能?也许你只是想做一个简单的例子,但颜色改变是不够的,因为 QAction 上的按钮仍然是可点击的,即使颜色改变了
  • 我刚刚使用其他东西而不是 QAction 编辑了我的示例,这个您可以随时启用和禁用。我认为您应该在必要时启用和禁用项目来管理您的项目。
  • 告诉我你想要你的状态。如果勾选了可以点击吗?如果检查它是灰色还是黑色?什么是所有状态案例。你能给我这个,以便我更好地理解你在寻找什么行为吗?
  • 您发布的已编辑解决方案不适用于 self.menu.setTearOffEnabled(True)。事实上,我有一个与您已经发布的类似的设置,但测试它的用户对它不满意,因为他们想要撕掉它。基本上,菜单中的禁用操作只有两种状态。检查,检查。一个启用的动作仍然只有两种状态,勾选,勾选,但是它可以被点击做X。唯一的区别是启用的可以被点击。我的解决方案使用一个复选框和一个按钮以及 QWidgetAction,就像你的一样,但是 tearOff 不起作用。
  • 对我来说这绝对是一个错误,而且在一些论坛上看到有人询问它,并且在 qt 的论坛上报告了一个错误。我正在尝试解决它,但到目前为止还没有那么成功。
猜你喜欢
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2013-12-11
  • 1970-01-01
  • 1970-01-01
  • 2017-11-06
相关资源
最近更新 更多