我正在尝试实现一个QDateTimeEdit子类,它将只显示时间部分(显示格式为“HH:mm”)和一个日历图标,单击该图标将触发日历弹出窗口,允许用户设置日期部分。我需要它有一个较短的datetime表示形式,因为很少需要更改日期
在这里添加.setCalendarPopup(True)是不够的,因为只有在格式字符串包含日期部分时才添加triggers,事实并非如此
我尝试过的(按钮嵌入取自this answer):
class ShortDatetimeEdit(QDateTimeEdit):
def __init__(self, *args, **kwargs):
super(ShortDatetimeEdit, self).__init__(*args, **kwargs)
self.setDisplayFormat("HH:mm")
self.setCurrentSection(QDateTimeEdit.MinuteSection)
self.setWrapping(True)
self.setCalendarPopup(True)
self._setup_date_picker()
def _setup_date_picker(self):
self.calendar_trigger = QToolButton(self)
self.calendar_trigger.setCursor(Qt.PointingHandCursor)
self.calendar_trigger.setFocusPolicy(Qt.NoFocus)
self.calendar_trigger.setIcon(QIcon("path/to/icon"))
self.calendar_trigger.setStyleSheet("background: transparent; border: none;")
self.calendar_trigger.setToolTip("Show calendar")
layout = QHBoxLayout(self)
layout.addWidget(self.calendar_trigger, 0, Qt.AlignRight)
layout.setSpacing(0)
self.calendar_trigger.clicked.connect(self._show_calendar)
def _show_calendar(self, _s):
self.calendarWidget().show() # everything breaks here, because calendarWidget() returns None
我的解决方案不起作用,因为self.calendarWidget()
返回None
(见最后一行)
所以问题是,有没有办法在不使用显示格式字符串中的日期部分的情况下从QDateTimeEdit触发日历弹出窗口(并使用它提供的值)
QDateTimeEdit是一种特殊类型的小部件,它也基于其显示格式实现其功能。长话短说,如果您设置的显示格式不显示任何日期值,它的行为将完全类似于QTimeEdit(如果您不显示时间值,它的行为将类似于QDateEdit)
这显然是出于设计原因,我想也是出于优化原因,但这种方法也会带来一些问题,就像您的案例一样
事实上,如果显示格式没有显示任何日期值,您甚至无法设置自己的日历小部件(Qt将对此发出警告)
为了实现您想要的,需要对现有方法进行一些重写。
还可以考虑通过添加子控件来尝试“破解”。不仅您的实现无法按预期工作,而且还可能导致意外的行为和绘制工件,这至少会使小部件难看(如果不是不可用的话)。最好的方法通常是尝试使用小部件已经提供的内容,即使它看起来可能比看起来更复杂。在这种情况下,您可以通过使用用于绘制和单击检测的QStyle函数,手动绘制组合框箭头,该箭头将显示为带有
setCalendarPopup(True)
的“正常”QDateTimeEdit最后,由于前面介绍的设计选择,每次更改日期、日期时间或显示格式时,如果显示格式不显示日期值,则日期范围将限制为当前日期,因此每次都需要将范围设置回原来的值,否则,将无法从日历中选择任何其他日期
下面是一个可能的实现:
一个重要的音符。即使在使用
setWrapping(True)
时,QDateTimeEdit(及其子类)也不会遵循时间逻辑:当在分钟部分从01:00
向下滚动时,结果将是01:59
,日期也是如此。如果您希望能够实际执行步进其他单元,那么还需要重写stepBy()
方法;这样,当您从分钟部分的01:00
向下滚动时,结果将是00:59
,如果您从00:00
向下滚动,它将转到前一天的23:59
显然,这是一种简化:对于完整显示的日期/时间显示格式,您应该添加相关的实现
最后(再次!),如果要确保鼠标滚轮始终响应鼠标光标下的部分,则需要在调用默认^{之前将文本光标放置到适当的位置
相关问题 更多 >
编程相关推荐