Пропадает placeholdertext после центрирования содержимого QLineEdit

После установки атрибута AlignCenter у QLineEdit фоновый текст показывается только когда виджет не в фокусе.

Как можно это исправить?

Минимально воспроизводимый пример:

import sys
import PyQt5
from PyQt5 import QtWidgets


class MainWindow(QtWidgets.QWidget):

    def __init__(self):
        super().__init__()
        lineedit = PyQt5.QtWidgets.QLineEdit(self)
        lineedit.setPlaceholderText('Placeholder Text')
        lineedit.setAlignment(PyQt5.QtCore.Qt.AlignCenter)


if __name__ == '__main__':
    app = PyQt5.QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

Ответы (2 шт):

Автор решения: S. Nick

placeholderText : QString

Это свойство содержит текст-заполнитель редактирования строки.

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

Обычно при редактировании пустой строки отображается текст-заполнитель, даже если он находится в фокусе.

Однако, если содержимое центрировано по горизонтали, текст заполнителя не отображается под курсором, когда редактирование строки находится в фокусе.

По умолчанию это свойство содержит пустую строку.

https://doc.qt.io/qt-5/qlineedit.html#placeholderText-prop

import sys
from PyQt5 import QtWidgets, QtCore


class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        
        self.lineedit = QtWidgets.QLineEdit(self)
        self.lineedit.textChanged.connect(self.text_changed)
        self.lineedit.setPlaceholderText('Placeholder Text')
        self.lineedit.setAlignment(QtCore.Qt.AlignCenter)      
        self.lineedit.setFocusPolicy(QtCore.Qt.ClickFocus)
        
        self.btn = QtWidgets.QPushButton("Button")

        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.lineedit)
        layout.addWidget(self.btn)
        
    def text_changed(self, text): 
        if self.lineedit.text() == '':
            self.btn.setFocus()
       

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка
Автор решения: type49

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

import sys
import PyQt5
from PyQt5 import QtWidgets


class LineEdit(QtWidgets.QLineEdit):

    def __init__(self, placeholder_text):
        super().__init__()
        self.resize(200, 200)
        self.setPlaceholderText(' ' * 20 + placeholder_text)

    def keyPressEvent(self, e):
        if not e.key() in [PyQt5.QtCore.Qt.Key_Shift, PyQt5.QtCore.Qt.Key_Control]:
            self.setAlignment(PyQt5.QtCore.Qt.AlignCenter)
            QtWidgets.QLineEdit.keyPressEvent(self, e)
        if self.text() == '':
            self.setAlignment(PyQt5.QtCore.Qt.AlignLeft)


class MainWindow(QtWidgets.QWidget):

    def __init__(self):
        super().__init__()
        self.setFixedSize(400, 100)
        line_edit = LineEdit('Placeholder Text')
        line_edit.setGeometry(100, 30, 200, 20)
        line_edit.setParent(self)


if __name__ == '__main__':
    app = PyQt5.QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
→ Ссылка