pyqt5: как скрыть заполнитель, когда виджет не включен?

#python #pyqt5 #placeholder #qwidget

#python #pyqt5 #плейсхолдер #qwidget

Вопрос:

Простым решением может быть:

 self.placeholder_text = "......."
...
...

#trigger the following code when enabled state of self.widget_name is changed

if(self.widget_name.isEnabled()):
     self.widget_name.setPlaceholderText(self.placeholder_text)
else:
     self.widget_name.setPlaceholderText("")
  

Но у меня много виджетов QLineEdit, поэтому я ищу решение для учета всех случаев.

Ответ №1:

Простым решением может быть перебор всех дочерних элементов QLineEdit:

 for lineEdit in self.findChildren(QtWidgets.QLineEdit):
    if lineEdit.isEnabled():
        lineEdit.setPlaceholderText(self.placeholder_text)
    else:
        lineEdit.setPlaceholderText("")
  

Но это, вероятно, не очень хороший подход, так как вам нужно постоянно проверять наличие всех виджетов, и могут быть некоторые изменения строки, для которых вы не хотите такого поведения.

Лучшим решением может быть подкласс редактирования строки и переопределение его changeEvent() :

 class MyLineEdit(QtWidgets.QLineEdit):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._placeholderText = self.placeholderText()

    def setPlaceholderText(self, text):
        self._placeholderText = text
        if self.isEnabled():
            super().setPlaceholderText(text)

    def changeEvent(self, event):
        if event.type() == QtCore.QEvent.EnabledChange:
            super().setPlaceholderText(
                self._placeholderText if self.isEnabled() else '')
        return super().changeEvent(event)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QWidget()
    layout = QtWidgets.QVBoxLayout(w)
    checkBox = QtWidgets.QCheckBox('Toggle enabled')
    layout.addWidget(checkBox)
    checkBox.setChecked(True)
    lineEdit = MyLineEdit(placeholderText='placeholder')
    layout.addWidget(lineEdit)
    checkBox.toggled.connect(lineEdit.setEnabled)
    w.show()
    sys.exit(app.exec_())
  

Приведенный выше код работает как для редактирования строк, созданных с placeholderText добавлением в конструктор (как в примере), так и с расширенными виджетами, используемыми в конструкторе.

Кроме того, вы можете добавить фильтр событий ко всем редактированиям строк, для которых вы хотите включить эту функцию.

         self.widget_name.installEventFilter(self)
        self.some_other_widget.installEventFilter(self)
        # ...

    def eventFilter(self, source, event):
        if (isinstance(source, QtWidgets.QLineEdit) and 
            event.type() == QtCore.QEvent.EnabledChange):
                source.setPlaceholderText(
                    self.placeholder_text if source.isEnabled() else '')
        return super().eventFilter(source, event)