Dirich
Dirich

Reputation: 442

pyqt dateEdit Max value

I have used pyqt designer to create a UI which has 2 dateEdit widgets which are meant to specify a time window. Both of them are set to popup a calendar to make the user life easier. I want to make sure that you can never obtain a time window where the "start" is bigger than the "end".

Example start and end are dateEdit widgets:

start.value = 20181010

end.value = 20181011

The user selects the start widget, the calendar pops up, and the user could select 20181012, which would lead to start.value > end.value, which would be nonsensical in my application.

I need to be able to enforce that this doesn't happen.

There are multiple ways I can approach the problem, but each one of them requires me to have something to hijack the callback temporarily, like ComboBox.currentIndexChanged in the case of ComboBox. I can't find a similar function for dateEdit.

The problem I face is to set the start date to be always lower or equal to the end date. I'm happy to have the end date always be fixed, so I only need to constrain one of the dateEdit. The issue is that the only "Max" constraint is a static one, so I would need to hijack the callback that triggers the open of the calendar so that I can insert code that reads the other dateEdit widget and sets its value as the max in the current one.

Any clue on how to do the hijacking? Alternative plans are well accepted too.

Upvotes: 1

Views: 935

Answers (1)

eyllanesc
eyllanesc

Reputation: 243955

You have to use the dateChanged signal to update the maximunDate or minimumDate, adding the appropriate offset according to the case:

from PyQt5 import QtCore, QtWidgets

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)

        self.date_from = QtWidgets.QDateEdit()
        self.date_to = QtWidgets.QDateEdit()
        for w in (self.date_from, self.date_to, ):
            w.setDisplayFormat("yyyyMMdd")
            w.setCalendarPopup(True)
        self.setup_date()

        lay = QtWidgets.QHBoxLayout(self)
        lay.addWidget(self.date_from)
        lay.addWidget(self.date_to)

    def setup_date(self):
        self.date_from.dateChanged.connect(self.on_date_from_changed)
        self.date_to.dateChanged.connect(self.on_date_to_changed)
        self.date_from.setDate(QtCore.QDate(2018, 10, 10))
        self.date_to.setDate(QtCore.QDate(2018, 10, 11))

    @QtCore.pyqtSlot(QtCore.QDate)
    def on_date_from_changed(self, date):
        self.date_to.setMinimumDate(date.addDays(1))

    @QtCore.pyqtSlot(QtCore.QDate)
    def on_date_to_changed(self, date):
        self.date_from.setMaximumDate(date.addDays(-1))

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

Upvotes: 1

Related Questions