一个可能的解决方案是使用 QTimeEdit,带有一个小的“hack”。
QTime 范围始终限制在 00:00:00 -> 23:59:59,但由于您只需要小时和分钟,因此您可以通过使用分钟和秒而不是小时和分钟来“伪造”它。显然,如果你还需要显示秒,这是不可能的。
诀窍是将时间范围限制为 00:00:00 -> 00:24:00(请注意,现在我们将最大值设置为 24 分钟)并始终从/到正确的格式。
我重写了 time 和 setTime 方法,以便您可以使用正确的 HH:MM 格式轻松获取/设置 QTime。 timeChanged 信号也以类似的方式被“覆盖”。
我还修改了stepBy 和stepEnabled 方法,因为默认情况下,步进操作(滚轮、箭头按钮、页面/箭头键)仅限于光标所在的部分:你不能走得更远 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_())