[Solved] Enhancing QDateEdit to allow for null/empty dates
-
I looking for recommendations on how to allow to enter and display null/empty dates in Qt using QDateEdit.
I very often need to enter a date interval that can have an open begin and/or end date and am used to have a UI that models this by simply entering an empty date field.
I'm aware that there are workarounds like using some "very old/new" dates to mimic the open limit of the interval or adding a checkbox to say there is no limit but IMHO simply using empty dates is a more intuitive UI.The only idea I came up with until now is to use a widget container that conditionally creates a regular QDateEdit when dealing with dates that cannot be empty or a simple QLineEdit widget for "nulleable" dates and add the date validation code to the QLineEdit. Unfortunately this solution does no longer allow to show a date picker for the "nulleable" dates.
-
[quote author="Gerolf" date="1294819109"]As the masks are set internally, I'm afraid, a QDateEdit can't be "empty"[/quote]
I'm not sure what you mean with "masks" but I imply that in your opinion deriving from QDateEdit to change the behavior is not possible? -
Nope. Also, I noticed that it is not possible to set an invalid date on a QDateEdit. It will be ignored it seems.
However, I think you may be able to adapt the current widget by subclassing or compositing it and using some CSS tricks. You could subclass (or composit in a new QWidget subclass) QDateEdit, and add a clear button on it using the same trick as you can use to "add a clear button to a QLineEdit":http://labs.qt.nokia.com/2007/06/06/lineedit-with-a-clear-button/. When you click the clear button, you can overlay something else, perhaps a QLabel, with a text "not set" or something like that and change the clear button for a set button.
You can then make your subclass (or composited widget) return an invalid QDateTime instead of a valid one if it is in the cleared state.
Perhaps not the prettiest solution, but it might work well enough.
-
[quote author="Dieter" date="1294820944"][quote author="Gerolf" date="1294819109"]As the masks are set internally, I'm afraid, a QDateEdit can't be "empty"[/quote]
I'm not sure what you mean with "masks" but I imply that in your opinion deriving from QDateEdit to change the behavior is not possible?[/quote]QDateEdit is an QAbstractSpinBox which internally has a QLIneEdit. This line edit has some masks and validators to ensure the display. This masks can't be changed by you, as you have no access to the line edit.
You could try to find the line edit by getChildren and then modify it, but I do not recommend that. It could work, but I perhaps also has some strange side effects.
-
[quote author="Gerolf" date="1294823113"]
QDateEdit is an QAbstractSpinBox which internally has a QLIneEdit. This line edit has some masks and validators to ensure the display. This masks can't be changed by you, as you have no access to the line edit.
You could try to find the line edit by getChildren and then modify it, but I do not recommend that. It could work, but I perhaps also has some strange side effects.[/quote]
I understand. Thank you for the details. -
[quote author="Andre" date="1294822105"]
However, I think you may be able to adapt the current widget by subclassing or compositing it and using some CSS tricks. You could subclass (or composit in a new QWidget subclass) QDateEdit, and add a clear button on it using the same trick as you can use to "add a clear button to a QLineEdit":http://labs.qt.nokia.com/2007/06/06/lineedit-with-a-clear-button/. When you click the clear button, you can overlay something else, perhaps a QLabel, with a text "not set" or something like that and change the clear button for a set button.
You can then make your subclass (or composited widget) return an invalid QDateTime instead of a valid one if it is in the cleared state.
Perhaps not the prettiest solution, but it might work well enough.[/quote]Thank you for the very creative suggestion!
I understand and like the idea of composing a new widget subclass by combining the actual QDateEdit and a "clear button" but I'm not absolutely sure what you mean with "using some CSS tricks".
Do you suggest that by using CSS styles I might be able to show an empty QDateEdit instead of having to overlay another QWidget? -
In our application we use a composite widget with a QDateTimeEdit and a checkbox, which when checked, enables the QDate/TimeEdit and when unchecked represents a null date. We do not have problems with usability with that, no complaints from our users. Also, it is only one click to reset it to null compared to 3 times delete the date :-) And not to mention that you cannot reset the date with the calendar popup (I'm sure there are users out there which do not know how to delete the date from the internal line edit)
-
No, I mean that by using CSS, you are able to position the clear button (and the other widgets) inside the QDateEdit itself in a nice way, and make sure that Qt doesn't draw over or under it. See the link I included for an idea of what I mean. It will look more natural that way. The CSS won't rid you of having to overlay something like a QLabel, unless you would accept a completely empty box as an acceptable representation of a null date. In that case, you could use CSS (or any other way to set the color) to make the text color the same as the background color.
-
[quote author="Volker" date="1294829498"]In our application we use a composite widget with a QDateTimeEdit and a checkbox, which when checked, enables the QDate/TimeEdit and when unchecked represents a null date. We do not have problems with usability with that, no complaints from our users. Also, it is only one click to reset it to null compared to 3 times delete the date :-) And not to mention that you cannot reset the date with the calendar popup (I'm sure there are users out there which do not know how to delete the date from the internal line edit)[/quote]
Thank you for the suggestion from the "real world". Sound like a interesting alternative UI design to the use of a clear button.
-
[quote author="Andre" date="1294829795"]No, I mean that by using CSS, you are able to position the clear button (and the other widgets) inside the QDateEdit itself in a nice way, and make sure that Qt doesn't draw over or under it. See the link I included for an idea of what I mean. It will look more natural that way. The CSS won't rid you of having to overlay something like a QLabel, unless you would accept a completely empty box as an acceptable representation of a null date. In that case, you could use CSS (or any other way to set the color) to make the text color the same as the background color.
[/quote]I understand! Thank you for making this crystal clear.
-
I have exactly the same problem: I try to migrate a MS Access application to Qt. There is a date field for a products table. For some products I have to store a "best before" date ("Mindesthaltbarkeit"), but for several products (like music instruments, jewels, etc...) there is no "best before" date. In MS access the user simply leave the field empty.
I have transfered the MS Access database to a sqlite3 database and now the new Qt frontend displays always the last displayed "best before" date when the value is null...
It would be great, if the QDateEdit can be evolved to handle null values as well.
Thanks,
Markus
-
We have created an extended version of QDateEdit that can handle null dates.
"QDateEditEx":https://github.com/doberkofler/QDateEditEx -
First of all: thanks for posting your solution.
However, it seems to me the class is not correct. It overrides date(), time() and dateTime(), but these functions are not virtual in [[doc:QDateEdit]] of which QDateEditEx is a subclass. That seems dangerous to me, as it won't work as a drop-in replacement of QDateEdit. If you use a QDateEditEx where a QDateEdit is expected, the results of calling these functions will be those defined in QDateEdit, not those from QDateEditEx.
Isn't it possible to provide the same feature by just reimplementing dateTimeFromText and textFromDateTime to work with empty strings and null dates? I didn't try it, but that seems to be the correct solution. Of course the features you have with the nullable property and the clear button are quite nice. Having the clear button in a date edit that accepts null input is a nice touch and also communicates to the user that an empty value is acceptable.
-
I have found a DateValidator that works fine with a QLineEdit and accepts null values:
http://www.qtforum.de/forum/viewtopic.php?f=7&t=900
Best regards,
Markus
-
this thread is very old, but i still may help others.
The QDateTimeEdit (and it's derives) have the method
@virtual QString textFromDateTime( const QDateTime & dateTime ) const;@
So you could subclass it and return any string you want and it will be displayed.
I don't think that QDateTimeEdit lets you set a invalid QDateTime value, but you could set a property on the widget to indicate a valid/invalid value state and return an appropriate custom string for invalid values or just return the base class implementation's return value. -
Here's another ugly workaround :
dateEdit->setSpecialValueText( " " ); dateEdit->setDate( QDate::fromString( "01/01/0001", "dd/MM/yyyy" ) );
- as the date is below the minimum, the widgets shows the special value text ( a space in this example )
- note that special text does not work with an empty string