如何为QTextEdit设置占位文本(PlaceHolderText)

6

我想设置一个 QTextEdit 的占位文本。我知道如何为 QLineEdit 设置它,有一个属性 setPlaceHolderText。但是这个属性对于 QTextEdit 不可用。请提供您宝贵的建议来解决这个问题。


1
与论坛网站不同,我们在 [so] 上不使用“谢谢”、“感激任何帮助”或签名。请参阅“应该从帖子中删除‘Hi’、‘thanks’、标语和问候语吗? - John Saunders
4个回答

3
使用QTextEdit的setTextCursor(QTextCursor&)函数。使用以下逻辑。
  QTextCursor textCursor;
  textCursor.setPosistion(0, QTextCursor::MoveAnchor); 
  textedit->setTextCursor( textCursor );

2
你实际上怎么做这个? - swdev

3

自从Qt 5.3版本以后,新增了该属性,在使用时你只需简单地调用setPlaceholderText函数即可。


2
我发现Rafe的回答有点不足,因为它不能正确地格式化文本。但是从jpo38的回答中,我在Qt5中找到了它的源代码,然后在Python中重新实现了我能够实现的部分。
它有一两个更改,但整体上看起来很好,它将文本放在正确的位置,并支持使用\n换行。
注意:这在PySide中使用Qt.py进行了测试,如果没有使用该文件,则需要将QtWidgets重新映射回QtGui
class QPlainTextEdit(QtWidgets.QPlainTextEdit):
    """QPlainTextEdit with placeholder text option.
    Reimplemented from the C++ code used in Qt5.
    """
    def __init__(self, *args, **kwargs):
        super(QPlainTextEdit, self).__init__(*args, **kwargs)

        self._placeholderText = ''
        self._placeholderVisible = False
        self.textChanged.connect(self.placeholderVisible)

    def placeholderVisible(self):
        """Return if the placeholder text is visible, and force update if required."""
        placeholderCurrentlyVisible = self._placeholderVisible
        self._placeholderVisible = self._placeholderText and self.document().isEmpty() and not self.hasFocus()
        if self._placeholderVisible != placeholderCurrentlyVisible:
            self.viewport().update()
        return self._placeholderVisible

    def placeholderText(self):
        """Return text used as a placeholder."""
        return self._placeholderText

    def setPlaceholderText(self, text):
        """Set text to use as a placeholder."""
        self._placeholderText = text
        if self.document().isEmpty():
            self.viewport().update()

    def paintEvent(self, event):
        """Override the paint event to add the placeholder text."""
        if self.placeholderVisible():
            painter = QtGui.QPainter(self.viewport())
            colour = self.palette().text().color()
            colour.setAlpha(128)
            painter.setPen(colour)
            painter.setClipRect(self.rect())
            margin = self.document().documentMargin()
            textRect = self.viewport().rect().adjusted(margin, margin, 0, 0)
            painter.drawText(textRect, QtCore.Qt.AlignTop | QtCore.Qt.TextWordWrap, self.placeholderText())
        super(QPlainTextEdit, self).paintEvent(event)

如果您希望文本保持显示直到您开始输入,只需删除not self.hasFocus()部分即可。

1
发现这有点有趣 - 我需要再次做这个,因为我忘记了上次放代码的地方。我看到了 Rafe 的答案,但它并不太好用,所以我向下滚动,看到了这个,真的很高兴有人花时间改进它。我试图点赞,结果发现这是我的答案。 - Peter
编程的工作方式很神秘。我们很高兴有这样一个网站!你让我的一天变得美好。 :D - Božo Stojković

2
我可以通过子类化和覆盖绘制事件来实现这一点:
class PlainTextEditWithPlaceholderText(QtGui.QPlainTextEdit):
    def __init__(self, parent=None):
        super(PlainTextEditWithPlaceholderText, self).__init__(parent)
        self.placeholderText = ""  # Qt-style camelCase

    def setPlaceholderText(self, text):
        self.placeholderText = text

    def paintEvent(self, _event):
        """
        Implements the same behavior as QLineEdit's setPlaceholderText()
        Draw the placeholder text when there is no text entered and the widget 
        doesn't have focus.
        """
        if self.placeholderText and not self.hasFocus() and not self.toPlainText():
            painter = QtGui.QPainter(self.viewport())

            color = self.palette().text().color()
            color.setAlpha(128)
            painter.setPen(color)

            painter.drawText(self.geometry().topLeft(), self.placeholderText)

        else:
            super(PlainTextEditWithPlaceholderText, self).paintEvent(event)

1
我不得不添加一个 self.viewport().update() 并稍微调整文本的位置,但除此之外一切都很好!谢谢! - meepzh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接