使用 QT Designer 时,如何使 PyQt QLineEdit 小部件比默认大小 17 x's 窄?

How do I make a PyQt QLineEdit widget narrower than the default size of 17 x's when using QT Designer?

当我使用 QT Designer 将 Qt 小部件放在 QHBoxLayout 布局中时,QLineEdit 小部件的最小宽度似乎为 17 x,至少如果这是当前源代码:

https://github.com/qt/qtbase/blob/dev/src/widgets/widgets/qlineedit.cpp

我找不到使 PyQt5 放置这些小部件的方法,因此它们将比默认值窄,但如果更改字体,大小仍会改变。

例如,QComboBox 将自动进行布局,使其宽度刚好足以显示作为可能值输入的最长文本。如果在 Designer 中为组合框输入的最长文本为 5 个字符,则组合框的布局将比最小 QLineEdit 宽度窄得多。如何使用 QT Designer 配置具有多个字符的 QLineEdit,以便它始终足够宽以容纳那么多字符,无论字体设置为什么,并且不更宽?我知道在 Designer 中我可以输入 maxLength,这将限制最大字符数 entered/displayed,但该设置当然对布局没有影响。

例如,我有一些文本框,其中的字符永远不会超过 5 个,而 Designer 的布局使它们至少比我需要的宽 3 倍。这是使用默认的“扩展”水平策略,但我已经尝试了许多水平策略和最小尺寸或基本尺寸值的组合。我想允许人们使用不同的字体大小,所以我不能安全地设置最大像素大小,也不能安全地设置固定的水平大小。 QComboBoxes 的处理正是我想要的 QLineEdits.

这一切都在 python 中,使用 Pip、pyqt5 5.15.6 和 pyqt5-qt5 5.15.2 上可用的最新版本的 PyQt5。

QLineEdit的size hint是从各个方面计算出来的,大部分都是使用私有函数,没有暴露给API,而且“x”的计数是硬编码的,这意味着这不能直接实现来自 Designer,并且只能通过 subclassing.

完成

虽然我们可以尝试模仿它的行为来实现自定义字符大小,但我认为对于简单的情况没有必要,所以我通过采用默认大小提示并根据 [=18 调整宽度来简化概念=]自定义字符提示与默认 17“x”计数之间的差异。

class CharHintLineEdit(QtWidgets.QLineEdit):
    _charHint = 17
    @QtCore.pyqtProperty(int)
    def charHint(self):
        return self._charHint

    @charHint.setter
    def charHint(self, chars):
        chars = max(1, chars)
        if self._charHint != chars:
            self._charHint = chars
            self.updateGeometry()

    def changeEvent(self, event):
        super().changeEvent(event)
        if event.type() in (event.FontChange, event.StyleChange):
            self.updateGeometry()

    def sizeHint(self):
        hint = super().sizeHint()
        if self._charHint != 17:
            # the 17 char width is hardcoded in Qt and there is no way to
            # retrieve it, it might change in the future, so, just to be safe,
            # we always set an arbitrary minimum based on half the height hint
            charSize = self.fontMetrics().horizontalAdvance('x')
            hint.setWidth(max(hint.height() // 2, hint.width() + 
                charSize * (self._charHint - 17)))
        return hint


if __name__ == '__main__':
    import sys
    from random import randrange
    app = QtWidgets.QApplication(sys.argv)
    test = QtWidgets.QWidget()
    layout = QtWidgets.QHBoxLayout(test)
    for i in range(5):
        charHint = randrange(5, 15)
        le = CharHintLineEdit(charHint=charHint, placeholderText=str(charHint))
        layout.addWidget(le)
    test.show()
    sys.exit(app.exec())

使用以上代码,您可以通过添加标准 QLineEdit 并使用 class 名称和相关 python 文件(不带文件扩展名)将其提升为 header。您还可以在 Designer 中将 charHint 设置为动态 属性,加载 UI 时将为小部件正确设置。