QWidgetAction проверяет состояние, не изменяющееся при использовании setDefaultWidget для QCheckBox - PullRequest
0 голосов
/ 23 января 2020

Я хочу создать меню с проверяемым списком. Чтобы предотвратить закрытие меню при нажатии действия, я устанавливаю DefaultWidget для QCheckBox. Проблема в том, что когда я пытаюсь получить isClicked из действия, похоже, оно не синхронизировано с флажком. Как получить значение действия, которое нужно изменить при нажатии флажка?

tool_button = QtWidgets.QToolButton()
menu = QtWidgets.QMenu()

check_box = QtWidgets.QCheckBox(menu)
check_box.setText("abc")
check_box.setChecked(True)
action_button = QtWidgets.QWidgetAction(menu)
action_button.setDefaultWidget(check_box)

menu.addAction(action_button)
tool_button.setMenu(menu)

print(check_box.text()) # returns abc
print(check_box.isChecked()) # returns True
print(action_button.isChecked()) # returns False - it's not picking up the values from check_box

1 Ответ

0 голосов
/ 23 января 2020

Поскольку QWidgetAction действует как своего рода контейнер для любого вида виджета, у него нет возможности узнать, может ли его defaultWidget вообще иметь какую-либо поддержку состояния bool, такого как "isChecked", поэтому вы должны предоставить его.

Самый простой способ - создать подкласс для указанного действия c класса QWidgetAction для этого действия и переопределить его метод isChecked(), чтобы он возвращал проверенное значение на основе своего виджета по умолчанию.

from PyQt5 import QtWidgets

class CheckableWidgetAction(QtWidgets.QWidgetAction):
    def setDefaultWidget(self, widget):
        super().setDefaultWidget(widget)
        try:
            # if the widget has the toggled signal, connect that signal to the
            # triggered signal
            widget.toggled.connect(self.triggered)
        except:
            pass

    def isChecked(self):
        try:
            return self.defaultWidget().isChecked()
        except:
            # failsafe, in case no default widget has been set or the provided
            # widget doesn't have a "checked" property
            return super().isChecked()


class Test(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QVBoxLayout(self)
        tool_button = QtWidgets.QToolButton()
        layout.addWidget(tool_button)
        menu = QtWidgets.QMenu()

        check_box = QtWidgets.QCheckBox(menu)
        check_box.setText("abc")
        check_box.setChecked(True)
        self.action_button = CheckableWidgetAction(menu)
        self.action_button.setDefaultWidget(check_box)
        self.action_button.triggered.connect(self.action_triggered)

        menu.addAction(self.action_button)
        tool_button.setMenu(menu)

        controlButton = QtWidgets.QPushButton('is checked?')
        layout.addWidget(controlButton)
        controlButton.clicked.connect(self.is_checked)

    def is_checked(self):
        print('checked is {}'.format(self.action_button.isChecked()))

    def action_triggered(self, state):
        print('triggered {}'.format(state))

if __name__ == '__main__':
    import sys
    a = QtWidgets.QApplication(sys.argv)
    test = Test()
    test.show()
    sys.exit(a.exec_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...