M
M
Michael2019-12-11 15:02:01
Python
Michael, 2019-12-11 15:02:01

How to bind objects in PyQt?

Hello!
I am developing a form using PyQt. I don't quite understand how the objects are connected to each other.
Example: I have a QLineEdit and a QCheckBox. When the status changes, the QCheckBox signals this and the QLineEdit becomes available or unavailable for input.
Right now I'm using the following structure:

self.MyChkbox.stateChanged.connect(
    lambda state: self.MyLineEdit.setReadOnly(
        True if state == 2 else False
    )
)

But it’s impossible, for example, passing through all the checkboxes in a loop in order to legalize each with its own lineEdit, and to connect a hundred checkboxes, I will have to repeat this construction a hundred times, each time explicitly pointing to a new field.
In my view, it should be possible to somehow group widgets so that each checkbox can be instructed to change the state of its widget.
Question: how can I avoid explicitly specifying names or references to objects in the code? Is there some kind of grouping of widgets that implements their connection for me? What to read?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
dndred, 2019-12-16
@dndred

class MyCheckBox(QCheckBox):
    def __init__(self, target_edit:QLineEdit, parent):
        super().__init__(parent)
        self._target_edit = target_edit
        self.stateChanged.connect(self._stateChanged_slot)

    def _stateChanged_slot(self):
        self._target_edit.setReadOnly(not self._target_edit.isReadOnly())

M
Michael, 2019-12-12
@1na1

So far, we managed to solve it by assigning a custom attribute (property) in each checkbox. The attribute points to the name of the field that belongs to this checkbox.
When constructing the form, I set the attributes like this:
Then, when initializing the window, I do this:

for checkbox in self.findChildren(QCheckBox): # Для всех чекбоксов формы
    if checkbox.property('field_name'): # Если чекбокс имеет свойство 'field_name'
        checkbox.stateChanged.connect( # Законнектить смену статуса чекбокса к функции
            # Функция поиска поля по имени объекта, содержащегося в свойстве отправителя (чекбокса)
            lambda state : self.findChild(QLineEdit, self.sender().property('field_name')).setReadOnly( 
                True if state == 2 else False # Выставить соответствующий статус доступности для ввода
            )
        )

I will be very glad to any other suggestions. Especially the link to the reading.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question