如何在 QlineEdit 中仅输入小时格式

How to enter only hour format in a QlineEdit

我想指定一个只能输入小时格式的QlineEdit (24:00);所以它只接受数字,它的最大值是 24:00,其中初始值为 00:00,当我修改小时时,它会自动保留“:”。 谢谢。

您可以使用“输入掩码”。

qline = QLineEdit("00:00")
qline.setInputMask("HH:HH")

备注

您的任务没有完全确定。违反格式怎么办?用有效的字符串覆盖条目?没做什么?发送错误消息?如果输入的时间大于 24 小时,是否已违反格式?

您在 Sven 回答后发表的评论表明您需要一个比您最初要求的更强大和更完整的解决方案。如果您想完全自定义哪些类型的字符可以/不能添加到 LineEdit 中,并且想要 运行 测试输入的函数,您将需要考虑使用 QValidator。

如果您不太确定 QValidator 是什么:

A QValidator is a class that provides validation of input text. When using one, you connect it to a QLineEdit, QSpinBox, or a QComboBox. Whenever the user is editing the connected field, after every character entered, it runs a validate function that can be implemented to run whatever logic you need to see if it is valid.

显示了使用 QRegExpValidator 解决您的问题的方法。但是,如果您仍然需要比 RegEx 所能提供的更多的检查(或者如果您不习惯使用 RegEx),您将需要继承 QValidator 并实现 validate 函数。

一个可能的解决方案是使用 QTimeEdit,带有一个小的“hack”。

QTime 范围始终限于 00:00:00 -> 23:59:59,但由于您只需要小时和分钟,因此您可以使用分钟和秒而不是小时和分钟来“伪造”它。显然,如果你还需要显示秒,这将是不可能的。

诀窍是将时间范围限制为 00:00:00 -> 00:24:00(请注意,现在我们将最大值设置为 24 分钟 )并且始终将 from/to 转换为正确的格式。

我重写了 timesetTime 方法,以便您可以使用正确的 HH:MM 格式轻松 get/set QTime。 timeChanged 信号也以类似的方式被“覆盖”。

我还修改了 stepBystepEnabled 方法,因为默认情况下步进操作(滚轮、箭头按钮、page/arrow 键)仅限于光标所在的部分:如果光标在分钟部分,则无法继续HH:59;通过我的实现,这个限制被移除了,你可以很容易地从 00:59 到 01:00.

class Time24Edit(QtWidgets.QTimeEdit):
    minTime = QtCore.QTime(0, 0)
    maxTime = QtCore.QTime(0, 24)
    _timeChanged = QtCore.pyqtSignal(QtCore.QTime)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setDisplayFormat('mm:ss')
        self.setMinimumTime(self.minTime)
        self.setMaximumTime(self.maxTime)

        # "substitute" the base timeChanged signal with the custom one so that
        # we emit the correct HH:MM time
        self._baseTimeChanged = self.timeChanged
        self._baseTimeChanged.connect(self._checkTime)
        self.timeChanged = self._timeChanged

    def _checkTime(self, time):
        self.timeChanged.emit(self.time())

    def stepBy(self, step):
        fakeTime = super().time()
        seconds = fakeTime.second() + fakeTime.minute() * 60
        if self.currentSection() == self.SecondSection:
            seconds += step
        elif self.currentSection() == self.MinuteSection:
            seconds += step * 60
        # "sanitize" the value to 0-1440 "minutes"
        seconds = max(0, min(1440, seconds))
        minutes, seconds = divmod(seconds, 60)
        super().setTime(QtCore.QTime(0, minutes, seconds))

    def stepEnabled(self):
        fakeTime = super().time()
        steps = 0
        if fakeTime > self.minTime:
            steps |= self.StepDownEnabled
        if fakeTime < self.maxTime:
            steps |= self.StepUpEnabled
        return steps

    def time(self):
        # convert minutes/seconds to hours/minutes
        fakeTime = super().time()
        return QtCore.QTime(fakeTime.minute(), fakeTime.second())

    def setTime(self, time):
        # convert hours/minutes to minutes/seconds
        super().setTime(QtCore.QTime(0, time.hour(), time.minute()))

if __name__ == '__main__':
    def signalTest(time):
        print(time)

    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Time24Edit()
    w.timeChanged.connect(signalTest)
    w.show()
    sys.exit(app.exec_())