0

我正在构建一个应用程序来从特定的 FTP 平台下载日志文件,我还希望用户能够在单独的 QDateTimeEdit 小部件中选择开始和停止日期。这将让程序选择适当的日志文件。

当用户连接到平台时,datetime会根据日志文件的可用性设置最小值和最大值. 小部件不会滚动到下个月。

我是否缺少启用或禁用翻转的属性?

我是否可以插入自定义 python (3.6) 代码来创建翻转?我的谷歌搜索除了2008 年的自定义 C++ 代码之外什么也没有产生stepBy,我无法很好地阅读它。

这是 .ui 文件的 XML 版本:

   <widget class="QDateTimeEdit" name="timestart">
    <property name="geometry">
     <rect>
      <x>510</x>
      <y>155</y>
      <width>126</width>
      <height>22</height>
     </rect>
    </property>
    <property name="alignment">
     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
    </property>
    <property name="displayFormat">
     <string notr="true">yyyy-MM-dd HH:mm:ss</string>
    </property>
   </widget>
   <widget class="QDateTimeEdit" name="timeend">
    <property name="geometry">
     <rect>
      <x>510</x>
      <y>205</y>
      <width>126</width>
      <height>22</height>
     </rect>
    </property>
    <property name="alignment">
     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
    </property>
    <property name="displayFormat">
     <string notr="true">yyyy-MM-dd HH:mm:ss</string>
    </property>
   </widget>

我意识到启用calendarPopup也是一种解决方法,但在设计方面,如果我能找到解决翻转问题的 Pythonic 方法,我宁愿不这样做。

4

2 回答 2

1

一个可能的解决方法是继承 QDateTimeEdit 并覆盖两者stepEnabled(负责显示启用的向上/向下箭头并允许实际的向上/向下步进操作),然后stepBy允许将日期更改为超出当前日/月/年的限制.

不幸的是,这并不能解决在选择适当的月份之前无法输入“无效”天数的问题(例如:您不能在 2 月输入 31),但是由于之间的相互作用,实现这样的结果非常复杂旋转框、光标和完成符。

在下面的代码中,我实现了它,以便所有有效的日期/时间字段实际上可以上下波动:月、日、小时、分钟和秒。

class DateTimeFix(QtWidgets.QDateTimeEdit):
    _overrideSteps = (
        QtWidgets.QDateTimeEdit.MonthSection, 
        QtWidgets.QDateTimeEdit.DaySection, 
        QtWidgets.QDateTimeEdit.HourSection, 
        QtWidgets.QDateTimeEdit.MinuteSection, 
        QtWidgets.QDateTimeEdit.SecondSection, 
    )
    def stepEnabled(self):
        if self.currentSection() in self._overrideSteps:
            return self.StepUpEnabled | self.StepDownEnabled
        return super().stepEnabled()

    def stepBy(self, steps):
        section = self.currentSection()
        if section not in self._overrideSteps:
            super().stepBy(steps)
            return
        dt = self.dateTime()
        section = self.currentSection()
        if section == self.MonthSection:
            dt = dt.addMonths(steps)
        elif section == self.DaySection:
            dt = dt.addDays(steps)
        elif section == self.HourSection:
            dt = dt.addSecs(3600 * steps)
        elif section == self.MinuteSection:
            dt = dt.addSecs(60 * steps)
        else:
            dt = dt.addSecs(steps)
        self.setDateTime(dt)

由于您在 Designer 中创建 UI,因此您需要在 Designer 中提升QDateTimeEdit 才能使用上述类。
简化的过程是:在设计器中右键单击 QDateTimeEdit 小部件并选择Promote to...,从对话框中的“Promoted class name”字段中键入“DateTimeFix”(类名),然后键入您将放置的文件的名称上面的类(没有.py扩展,就像你对导入所做的那样),确保基类名称仍然正确(QDateTimeEdit),单击“添加”,然后单击“提升” 。在此过程之后,您可以提升您在该用户界面中可能拥有的所有其他 QDateTimeEdit(只需右键单击它们并从新的“提升到”子菜单中选择它)。以获得更详细的解释。

于 2021-04-11T13:49:45.543 回答
0

我使用了上面@musicamante 所示的代码片段,并进行了一些调整,可能是因为我使用的是 PyQt6。(基本上,将这些.Section和添加.StepEnabledFlag到枚举属性)

from PyQt6.QtWidgets import QDateTimeEdit

class DateTimeFix(QDateTimeEdit):
    _overrideSteps = (
        QDateTimeEdit.Section.MonthSection, 
        QDateTimeEdit.Section.DaySection, 
        QDateTimeEdit.Section.HourSection, 
        QDateTimeEdit.Section.MinuteSection, 
        QDateTimeEdit.Section.SecondSection, 
    )
    def stepEnabled(self):
        if self.currentSection() in self._overrideSteps:
            return self.StepEnabledFlag.StepUpEnabled | self.StepEnabledFlag.StepDownEnabled
        return super().stepEnabled()

    def stepBy(self, steps):
        section = self.currentSection()
        if section not in self._overrideSteps:
            super().stepBy(steps)
            return
        dt = self.dateTime()
        section = self.currentSection()
        if section == self.Section.MonthSection:
            dt = dt.addMonths(steps)
        elif section == self.Section.DaySection:
            dt = dt.addDays(steps)
        elif section == self.Section.HourSection:
            dt = dt.addSecs(3600 * steps)
        elif section == self.Section.MinuteSection:
            dt = dt.addSecs(60 * steps)
        else:
            dt = dt.addSecs(steps)
        self.setDateTime(dt)

于 2021-12-20T22:16:04.117 回答