Two QlineEdit box, which interrelated - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: Two QlineEdit box, which interrelated (/thread-28974.html) |
Two QlineEdit box, which interrelated - GMCobraz - Aug-12-2020 Hi guys, I have a general question here. How can I make sure two QLineEdit box are interrelated? I haven't code, just to get an idea here. For example, box A and B are interrelated. When I change box A, B will update too. But how I change box B and update box A? My understanding is the code is flow from box A to box B, the value from box A will overwrite box B changed by user earlier. Should I implement something like textChanged or valueChanged? Thank you very much. RE: Two QlineEdit box, which interrelated - deanhystad - Aug-14-2020 This question sounds familiar. First I would ask myself why do I have two line edit boxes that are interrelated. Assuming this is a good idea in your case, when do you want to "sync" the entries? While typing? When the control loses focus? When enter is pressed? I found QLineEdit lacking and added the concept of "accept". I wanted to ignore typing and only sent a notification when the enter key was pressed or if the QLineEdit lost focus. When this happens my modified QLineEdit emits a valuechanged signal. class LineEdit(QLineEdit): """QLineEdit with revert on focus out and valuechanged signal. valuechanged differs from textChanged in that the value does not change until the enter/return key is pressed. If I lose focus before enter/return is pressed I perform the selected revert action """ # Instance variables revert: bool # Action taken when control loses focus _value: str # Accepted text # This acts like an ivar but must be declared here. Why? valuechanged = Signal(str) def __init__(self, *args, revert=True, **kv_args): super().__init__(*args, **kv_args) self._value = '' self.revert = revert def event(self, ev): """Override QLineEdit event method. Intercept tab key press. When tab pressed accept the text and navigate to the next control. Also capture return key pressed since processing is the same as tab key. Capture focus out event and revert to last accepted text """ if ev.type() == QEvent.KeyPress: if ev.key() in (int(Qt.Key_Tab), int(Qt.Key_Return)): self._accepttext() elif ev.type() == QEvent.FocusOut: self._focusout() return super().event(ev) def _focusout(self): """Called when control loses focus. Based on revert mode either revert the last accepted text, or treat as if return was pressed""" if self._value != self.text(): if self.revert: self.setText(self._value) else: self._accepttext() def _accepttext(self): """Called when changed text is accepted. Emit valuechanged signal""" self._value = self.text() self.valuechanged.emit(self._value) def clear(self): """Set to no display""" self.value = '' @property def value(self): """Accepted text""" return self._value @value.setter def value(self, value): self._value = value self.setText(value)Once you how notification should work, it comes down to either using one of the available signals, or subclassing QLineEdit to act the way you want. Eventually you will call a function that updates the controls. Depending on how they are related this may be the same function for both, or separate functions for each. You will have to implement some kind of lock to prevent the A callback changing B from calling the B callback. For this I use a common variable in the callback functions. def a_changed() if not lockedout lockedout = True # set value of B lockedout = False def b_changed() if not lockedout lockedout = True # set value of A lockedout = False |