MonthGrid.clicked() behavior
-
Hi all -
Here's the code:
class ScheduleModel : public QAbstractListModel { Q_INVOKABLE void datePicked(QDateTime date) { qDebug() << __PRETTY_FUNCTION__ << "date picked:" << date; } ...
and:
MonthGrid { id: monthGrid onClicked: (date) => { console.log("date clicked is " + date) scheduleModel.datePicked(date) } ...
Everything seems to work, but the output is a bit curious: if I click on August 16 2023, here's what I get:
qml: date clicked is Tue Aug 15 17:00:00 2023 GMT-0700 void ScheduleModel::datePicked(QDateTime) date picked: QDateTime(2023-08-15 17:00:00.000 Pacific Daylight Time Qt::LocalTime)
I'm not sure how to interpret this - I guess the date/time returned is the first second of the 16th, but to represent it as the 15th strikes me as a little weird. I guess this is just how it works?
If I change my QDateTime to a QDate in my C++, the qDebug() outputs the correct date.
Anyway, I'm only posting this because I'm curious if I'm doing it right - comments welcome.
Thanks...
-
Hi all -
Here's the code:
class ScheduleModel : public QAbstractListModel { Q_INVOKABLE void datePicked(QDateTime date) { qDebug() << __PRETTY_FUNCTION__ << "date picked:" << date; } ...
and:
MonthGrid { id: monthGrid onClicked: (date) => { console.log("date clicked is " + date) scheduleModel.datePicked(date) } ...
Everything seems to work, but the output is a bit curious: if I click on August 16 2023, here's what I get:
qml: date clicked is Tue Aug 15 17:00:00 2023 GMT-0700 void ScheduleModel::datePicked(QDateTime) date picked: QDateTime(2023-08-15 17:00:00.000 Pacific Daylight Time Qt::LocalTime)
I'm not sure how to interpret this - I guess the date/time returned is the first second of the 16th, but to represent it as the 15th strikes me as a little weird. I guess this is just how it works?
If I change my QDateTime to a QDate in my C++, the qDebug() outputs the correct date.
Anyway, I'm only posting this because I'm curious if I'm doing it right - comments welcome.
Thanks...
@mzimmers
Well, you know what this is all about because of the funny country you live in ;-) We own "proper" time here in England (UTC/GMT), you colonials have to do timezone adjustments as a penalty for living in a backwater :)The full datetime being returned is clearly August 16 at 00:00:00 midnight. Doubtless because it's only a date picker, not datetime, so it picks 0 for the hour part. Then you are in EST, which is -05:00 hours back, i.e. 17:00:00 on previous day, August 15th.
So you are showing a UTC/GMT midnight time in your local time. Meanwhile, if you use
QDate
instead ofQDateTime
it appears that does not converted for timezone since it has no time, hence you get to see the original date of 16th August.As you are aware I don't know what facilities you have in QML. But you need to do something about not treating the original as 00:00:00 UTC/GMT and then displaying it converted to local time. Perhaps from JavaScript you should be doing something more sophisticated than just printing
date
, it may well have some timezone aware methods?P.S.
I'm not prepared to go through the previous exactly, but I note that actually Pacific Time seems to be involved here, which is actually UTC-07:00 hours rather than EST which is -05:00 hours. Not to mention, there is daylight time involved here, which should make it -06:00 hours. But you get the drift..... -
Hi all -
Here's the code:
class ScheduleModel : public QAbstractListModel { Q_INVOKABLE void datePicked(QDateTime date) { qDebug() << __PRETTY_FUNCTION__ << "date picked:" << date; } ...
and:
MonthGrid { id: monthGrid onClicked: (date) => { console.log("date clicked is " + date) scheduleModel.datePicked(date) } ...
Everything seems to work, but the output is a bit curious: if I click on August 16 2023, here's what I get:
qml: date clicked is Tue Aug 15 17:00:00 2023 GMT-0700 void ScheduleModel::datePicked(QDateTime) date picked: QDateTime(2023-08-15 17:00:00.000 Pacific Daylight Time Qt::LocalTime)
I'm not sure how to interpret this - I guess the date/time returned is the first second of the 16th, but to represent it as the 15th strikes me as a little weird. I guess this is just how it works?
If I change my QDateTime to a QDate in my C++, the qDebug() outputs the correct date.
Anyway, I'm only posting this because I'm curious if I'm doing it right - comments welcome.
Thanks...
@mzimmers here a simple calendar of my QML component collection:
// main.qml ApplicationWindow { width: 640 height: 640 visible: true Button { anchors.centerIn: parent text: "Open Calendar" onClicked: calendar.open() } CalendarInput { id: calendar // you can set any date selectedDate: new Date() // to be used as dateFrom or dateTo input // to include or exclude the selected day // CalendarInput.DayType.EndOfDay // CalendarInput.DayType.StartOfDay dateType: CalendarInput.DayType.StartOfDay // limit year selection yearFrom: 2018 yearTo: 2027 // styling backgroundColor: "#F9F9F9" headerPointSize: 22 defaultPointSize: 12 accentColor: "teal" textColorOnAccent: "white" fontColor: "#2C2E35" // called once the "confirm" button is clicked onConfirm: { console.debug("Date:", selectedDate) console.debug("UNIX Timestamp:", unix) } } }
// CalendarInput.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import Qt.labs.calendar 1.0 Popup { id: calendar // center calendar popup in main window/overlay parent: Overlay.overlay ? Overlay.overlay : Window.contentItem anchors.centerIn: parent width: 500 height: 500 background: Rectangle { color: backgroundColor radius: 10 } // only close calendar via the provided buttons closePolicy: Popup.NoAutoClose modal: true // enum for dayType, which gets applied onOpen and before onConfirm enum DayType { StartOfDay, EndOfDay } // set default dateType to StartOfDay property int dateType: CalendarInput.DayType.StartOfDay // uses setHours instead of setUTCHours as calendar is localized function applyDayType() { let _date = selectedDate if (dateType === CalendarInput.DayType.StartOfDay) _date.setHours(0, 0, 0, 0) else _date.setHours(23, 59, 59, 999) selectedDate = _date } // background color of calendar popup property color backgroundColor: "#F9F9F9" // pointSize of month-year label property int headerPointSize: 22 // default pointSize of texts property int defaultPointSize: 12 // background color for highlighting selected date property color accentColor: "#017EAF" // text color for accent background property color textColorOnAccent: "white" // general font color for all texts property color fontColor: "#2C2E35" // selected date the calendar gets initialized with property date selectedDate: new Date() // read the unix timestamp of the selectedDate readonly property int unix: selectedDate.getTime() / 1000 // year select list begin // default : epoch property int yearFrom: 1970 // year select list end // default : current year property int yearTo: new Date().getFullYear() // hidden properties; should not be visible from outside QtObject { id: privateProperties property date initialDate } onOpened: { // apply day type StartOfDay | EndOfDay (00:00:00 | 23:59:59) applyDayType() // save inital date for restoring, in case user clicks cancel privateProperties.initialDate = selectedDate calendar.forceActiveFocus() } // signals for calendar // e.g. onConfirm:{myDateProp = selectedDate} signal confirm signal cancel // apply selected date to grid date so grid will show month // with selected date, if calendar gets reopend onConfirm: { monthGrid.gridDate = selectedDate calendar.close() } // reset grid date and selected date, if user clicks cancel onCancel: { monthGrid.gridDate = privateProperties.initialDate selectedDate = privateProperties.initialDate calendar.close() } // update year range if it got changed onYearFromChanged: yearList.applyYearRange() onYearToChanged: yearList.applyYearRange() // toggles month-year select function showYearSelect(show) { yearSelect.visible = show } // gets visible if user clicks the month-year label above date grid // simple selection of month and year via 2 ListViews ColumnLayout { id: yearSelect visible: false anchors.fill: parent anchors.margins: 20 RowLayout { ListView { id: monthList clip: true Layout.fillHeight: true Layout.fillWidth: true // show selected item in the center preferredHighlightBegin: height / 2 preferredHighlightEnd: height / 2 highlightRangeMode: ListView.StrictlyEnforceRange currentIndex: monthGrid.month spacing: 10 // 12 months model: 12 delegate: Rectangle { width: monthList.width height: monthName.height * 1.25 color: monthGrid.month === index ? accentColor : "transparent" radius: 5 Text { id: monthName anchors.centerIn: parent width: parent.width - 20 horizontalAlignment: Text.AlignHCenter font.pointSize: headerPointSize * 0.8 wrapMode: Text.Wrap // display month name based on locale (january = 0) text: Qt.locale().monthName(index, Locale.LongFormat) color: monthGrid.month === index ? textColorOnAccent : fontColor } MouseArea { anchors.fill: parent onClicked: { let _date = monthGrid.gridDate _date.setMonth(index) monthGrid.gridDate = _date } } } } ListView { id: yearList clip: true Layout.fillHeight: true Layout.fillWidth: true spacing: 10 model: [] preferredHighlightBegin: height / 2 preferredHighlightEnd: height / 2 highlightRangeMode: ListView.StrictlyEnforceRange // set initial year model based on "yearFrom" and "yearTo" // properties of calendar Component.onCompleted: { applyYearRange() } function applyYearRange() { let _model = [] let _currentIndex = 0 for (var i = yearFrom; i <= yearTo; i++) { _model.push(i) if (i === monthGrid.year) _currentIndex = _model.length - 1 } model = _model currentIndex = _currentIndex } // update current index for highlighting selected item function updateCurrentIndex() { for (let i in model) { if (model[i] === monthGrid.year) { currentIndex = i break } } } delegate: Rectangle { width: yearList.width height: year.height * 1.25 color: monthGrid.year === modelData ? accentColor : "transparent" radius: 5 Text { id: year anchors.centerIn: parent width: parent.width - 20 horizontalAlignment: Text.AlignHCenter font.pointSize: headerPointSize * 0.8 wrapMode: Text.Wrap text: modelData color: monthGrid.year === modelData ? textColorOnAccent : fontColor } MouseArea { anchors.fill: parent onClicked: { let _date = monthGrid.gridDate _date.setYear(modelData) monthGrid.gridDate = _date } } } } } Text { Layout.alignment: Qt.AlignRight horizontalAlignment: Text.AlignRight font: monthGrid.font text: qsTr("Select date") MouseArea { anchors.fill: parent onClicked: showYearSelect(false) } } } GridLayout { visible: !yearSelect.visible anchors.fill: parent anchors.margins: 20 columns: 1 rowSpacing: 20 RowLayout { Layout.fillWidth: true height: monthYearLabel.height * 1.5 Image { id: previousMonthIcon verticalAlignment: Qt.AlignVCenter // @svg 'chevron-left' from https://heroicons.com/ source: "data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"" + fontColor + "\" stroke-width=\"2\"> <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" /> </svg>" MouseArea { anchors.fill: parent onClicked: { monthGrid.addMonths(-1) } } } Text { id: monthYearLabel Layout.fillWidth: true verticalAlignment: Qt.AlignVCenter horizontalAlignment: Text.AlignHCenter font.pointSize: headerPointSize // display month name based on locale text: Qt.locale().monthName( monthGrid.month, Locale.LongFormat) + " " + monthGrid.year MouseArea { anchors.fill: parent // open month-year select onClicked: showYearSelect(true) } } Image { id: nextMonthIcon verticalAlignment: Qt.AlignVCenter // @svg 'chevron-right' from https://heroicons.com/ source: "data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"" + fontColor + "\" stroke-width=\"2\"> <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\" /> </svg>" MouseArea { anchors.fill: parent onClicked: { monthGrid.addMonths(1) } } } } // days of the week based on locale DayOfWeekRow { locale: monthGrid.locale Layout.fillWidth: true delegate: Text { Layout.fillHeight: true Layout.fillWidth: true text: model.shortName font: monthGrid.font horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } // month grid displaying the selectable dates MonthGrid { id: monthGrid locale: Qt.locale() Layout.fillWidth: true Layout.fillHeight: true font.pointSize: defaultPointSize // initialize with selected date of calendar property date gridDate: selectedDate month: gridDate.getMonth() year: gridDate.getFullYear() // add day property for simplyfication property int day: gridDate.getDate() // update year-select current index onYearChanged: yearList.updateCurrentIndex() function addMonths(amount) { let _date = gridDate _date.setMonth(_date.getMonth() + (amount)) gridDate = _date } delegate: Item { id: delegateItem Layout.fillHeight: true Layout.fillWidth: true // check if delegate is the selected day of the calendar property bool isSelectedDay: (model.year === selectedDate.getFullYear() && model.month === selectedDate.getMonth() && model.day === selectedDate.getDate( )) Rectangle { anchors.centerIn: parent // smaller side gets base length for highlight circle width: Math.min(parent.width, parent.height) height: width radius: width / 2 color: delegateItem.isSelectedDay ? accentColor : "transparent" Text { anchors.centerIn: parent opacity: model.month === monthGrid.month ? 1 : 0.25 color: delegateItem.isSelectedDay ? textColorOnAccent : fontColor text: model.day font: monthGrid.font } } } onClicked: { // if user selects date, apply it to selectedDate selectedDate = date } } RowLayout { Layout.fillWidth: true height: childrenRect.height spacing: 20 Row { Layout.fillWidth: true Text { font: monthGrid.font text: qsTr("Today") MouseArea { anchors.fill: parent // set selected date and grid view to "today" onClicked: { selectedDate = new Date() monthGrid.gridDate = selectedDate } } } } Row { spacing: 20 Text { horizontalAlignment: Text.AlignHCenter font: monthGrid.font text: qsTr("Cancel") MouseArea { anchors.fill: parent // emit cancel() signal of calendar onClicked: calendar.cancel() } } Text { horizontalAlignment: Text.AlignHCenter font: monthGrid.font text: qsTr("Confirm") MouseArea { anchors.fill: parent onClicked: { // apply day type before emitting confirm() signal applyDayType() calendar.confirm() } } } } } } enter: Transition { NumberAnimation { property: "opacity" from: 0.0 to: 1.0 duration: 180 } NumberAnimation { property: "scale" from: 0 to: 1 duration: 210 } } exit: Transition { NumberAnimation { property: "opacity" from: 1.0 to: 0.0 duration: 150 } SequentialAnimation { NumberAnimation { property: "scale" from: 1 to: 0.1 duration: 155 } NumberAnimation { property: "scale" from: 0.1 to: 1 duration: 1 } } } }
-
@mzimmers
Well, you know what this is all about because of the funny country you live in ;-) We own "proper" time here in England (UTC/GMT), you colonials have to do timezone adjustments as a penalty for living in a backwater :)The full datetime being returned is clearly August 16 at 00:00:00 midnight. Doubtless because it's only a date picker, not datetime, so it picks 0 for the hour part. Then you are in EST, which is -05:00 hours back, i.e. 17:00:00 on previous day, August 15th.
So you are showing a UTC/GMT midnight time in your local time. Meanwhile, if you use
QDate
instead ofQDateTime
it appears that does not converted for timezone since it has no time, hence you get to see the original date of 16th August.As you are aware I don't know what facilities you have in QML. But you need to do something about not treating the original as 00:00:00 UTC/GMT and then displaying it converted to local time. Perhaps from JavaScript you should be doing something more sophisticated than just printing
date
, it may well have some timezone aware methods?P.S.
I'm not prepared to go through the previous exactly, but I note that actually Pacific Time seems to be involved here, which is actually UTC-07:00 hours rather than EST which is -05:00 hours. Not to mention, there is daylight time involved here, which should make it -06:00 hours. But you get the drift.....@JonB said in MonthGrid.clicked() behavior:
@mzimmers
Well, you know what this is all about because of the funny country you live in ;-) We own "proper" time here in England (UTC/GMT), you colonials have to do timezone adjustments as a penalty for living in a backwater :)Yeah, yeah...who's got the Ryder Cup again? Want to place a bet on this year's edition?
The full datetime being returned is clearly August 16 at 00:00:00 midnight. Doubtless because it's only a date picker, not datetime, so it picks 0 for the hour part. Then you are in EST, which is -05:00 hours back, i.e. 17:00:00 on previous day, August 15th.
I'm actually in PDT, not EST, which explains the "17:00:00" which is 7 (not 5) hours behind midnight. So, yeah, as I surmised, it's taking the first instance of the day.
So you are showing a UTC/GMT midnight time in your local time. Meanwhile, if you use
QDate
instead ofQDateTime
it appears that does not converted for timezone since it has no time, hence you get to see the original date of 16th August.Ahhh...that makes sense.
As you are aware I don't know what facilities you have in QML. But you need to do something about not treating the original as 00:00:00 UTC/GMT and then displaying it converted to local time. Perhaps from JavaScript you should be doing something more sophisticated than just printing
date
, it may well have some timezone aware methods?That's worth looking into...thanks for the suggestion.
EDIT:
The JS code was a little fussy, but I think I got it working with this:
onClicked: (date) => { var offset = date.getTimezoneOffset() var localDate = new Date(date.getTime() + (offset * 60000)) scheduleModel.datePicked(localDate) }
-
@mzimmers here a simple calendar of my QML component collection:
// main.qml ApplicationWindow { width: 640 height: 640 visible: true Button { anchors.centerIn: parent text: "Open Calendar" onClicked: calendar.open() } CalendarInput { id: calendar // you can set any date selectedDate: new Date() // to be used as dateFrom or dateTo input // to include or exclude the selected day // CalendarInput.DayType.EndOfDay // CalendarInput.DayType.StartOfDay dateType: CalendarInput.DayType.StartOfDay // limit year selection yearFrom: 2018 yearTo: 2027 // styling backgroundColor: "#F9F9F9" headerPointSize: 22 defaultPointSize: 12 accentColor: "teal" textColorOnAccent: "white" fontColor: "#2C2E35" // called once the "confirm" button is clicked onConfirm: { console.debug("Date:", selectedDate) console.debug("UNIX Timestamp:", unix) } } }
// CalendarInput.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import Qt.labs.calendar 1.0 Popup { id: calendar // center calendar popup in main window/overlay parent: Overlay.overlay ? Overlay.overlay : Window.contentItem anchors.centerIn: parent width: 500 height: 500 background: Rectangle { color: backgroundColor radius: 10 } // only close calendar via the provided buttons closePolicy: Popup.NoAutoClose modal: true // enum for dayType, which gets applied onOpen and before onConfirm enum DayType { StartOfDay, EndOfDay } // set default dateType to StartOfDay property int dateType: CalendarInput.DayType.StartOfDay // uses setHours instead of setUTCHours as calendar is localized function applyDayType() { let _date = selectedDate if (dateType === CalendarInput.DayType.StartOfDay) _date.setHours(0, 0, 0, 0) else _date.setHours(23, 59, 59, 999) selectedDate = _date } // background color of calendar popup property color backgroundColor: "#F9F9F9" // pointSize of month-year label property int headerPointSize: 22 // default pointSize of texts property int defaultPointSize: 12 // background color for highlighting selected date property color accentColor: "#017EAF" // text color for accent background property color textColorOnAccent: "white" // general font color for all texts property color fontColor: "#2C2E35" // selected date the calendar gets initialized with property date selectedDate: new Date() // read the unix timestamp of the selectedDate readonly property int unix: selectedDate.getTime() / 1000 // year select list begin // default : epoch property int yearFrom: 1970 // year select list end // default : current year property int yearTo: new Date().getFullYear() // hidden properties; should not be visible from outside QtObject { id: privateProperties property date initialDate } onOpened: { // apply day type StartOfDay | EndOfDay (00:00:00 | 23:59:59) applyDayType() // save inital date for restoring, in case user clicks cancel privateProperties.initialDate = selectedDate calendar.forceActiveFocus() } // signals for calendar // e.g. onConfirm:{myDateProp = selectedDate} signal confirm signal cancel // apply selected date to grid date so grid will show month // with selected date, if calendar gets reopend onConfirm: { monthGrid.gridDate = selectedDate calendar.close() } // reset grid date and selected date, if user clicks cancel onCancel: { monthGrid.gridDate = privateProperties.initialDate selectedDate = privateProperties.initialDate calendar.close() } // update year range if it got changed onYearFromChanged: yearList.applyYearRange() onYearToChanged: yearList.applyYearRange() // toggles month-year select function showYearSelect(show) { yearSelect.visible = show } // gets visible if user clicks the month-year label above date grid // simple selection of month and year via 2 ListViews ColumnLayout { id: yearSelect visible: false anchors.fill: parent anchors.margins: 20 RowLayout { ListView { id: monthList clip: true Layout.fillHeight: true Layout.fillWidth: true // show selected item in the center preferredHighlightBegin: height / 2 preferredHighlightEnd: height / 2 highlightRangeMode: ListView.StrictlyEnforceRange currentIndex: monthGrid.month spacing: 10 // 12 months model: 12 delegate: Rectangle { width: monthList.width height: monthName.height * 1.25 color: monthGrid.month === index ? accentColor : "transparent" radius: 5 Text { id: monthName anchors.centerIn: parent width: parent.width - 20 horizontalAlignment: Text.AlignHCenter font.pointSize: headerPointSize * 0.8 wrapMode: Text.Wrap // display month name based on locale (january = 0) text: Qt.locale().monthName(index, Locale.LongFormat) color: monthGrid.month === index ? textColorOnAccent : fontColor } MouseArea { anchors.fill: parent onClicked: { let _date = monthGrid.gridDate _date.setMonth(index) monthGrid.gridDate = _date } } } } ListView { id: yearList clip: true Layout.fillHeight: true Layout.fillWidth: true spacing: 10 model: [] preferredHighlightBegin: height / 2 preferredHighlightEnd: height / 2 highlightRangeMode: ListView.StrictlyEnforceRange // set initial year model based on "yearFrom" and "yearTo" // properties of calendar Component.onCompleted: { applyYearRange() } function applyYearRange() { let _model = [] let _currentIndex = 0 for (var i = yearFrom; i <= yearTo; i++) { _model.push(i) if (i === monthGrid.year) _currentIndex = _model.length - 1 } model = _model currentIndex = _currentIndex } // update current index for highlighting selected item function updateCurrentIndex() { for (let i in model) { if (model[i] === monthGrid.year) { currentIndex = i break } } } delegate: Rectangle { width: yearList.width height: year.height * 1.25 color: monthGrid.year === modelData ? accentColor : "transparent" radius: 5 Text { id: year anchors.centerIn: parent width: parent.width - 20 horizontalAlignment: Text.AlignHCenter font.pointSize: headerPointSize * 0.8 wrapMode: Text.Wrap text: modelData color: monthGrid.year === modelData ? textColorOnAccent : fontColor } MouseArea { anchors.fill: parent onClicked: { let _date = monthGrid.gridDate _date.setYear(modelData) monthGrid.gridDate = _date } } } } } Text { Layout.alignment: Qt.AlignRight horizontalAlignment: Text.AlignRight font: monthGrid.font text: qsTr("Select date") MouseArea { anchors.fill: parent onClicked: showYearSelect(false) } } } GridLayout { visible: !yearSelect.visible anchors.fill: parent anchors.margins: 20 columns: 1 rowSpacing: 20 RowLayout { Layout.fillWidth: true height: monthYearLabel.height * 1.5 Image { id: previousMonthIcon verticalAlignment: Qt.AlignVCenter // @svg 'chevron-left' from https://heroicons.com/ source: "data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"" + fontColor + "\" stroke-width=\"2\"> <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 19l-7-7 7-7\" /> </svg>" MouseArea { anchors.fill: parent onClicked: { monthGrid.addMonths(-1) } } } Text { id: monthYearLabel Layout.fillWidth: true verticalAlignment: Qt.AlignVCenter horizontalAlignment: Text.AlignHCenter font.pointSize: headerPointSize // display month name based on locale text: Qt.locale().monthName( monthGrid.month, Locale.LongFormat) + " " + monthGrid.year MouseArea { anchors.fill: parent // open month-year select onClicked: showYearSelect(true) } } Image { id: nextMonthIcon verticalAlignment: Qt.AlignVCenter // @svg 'chevron-right' from https://heroicons.com/ source: "data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"" + fontColor + "\" stroke-width=\"2\"> <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5l7 7-7 7\" /> </svg>" MouseArea { anchors.fill: parent onClicked: { monthGrid.addMonths(1) } } } } // days of the week based on locale DayOfWeekRow { locale: monthGrid.locale Layout.fillWidth: true delegate: Text { Layout.fillHeight: true Layout.fillWidth: true text: model.shortName font: monthGrid.font horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } // month grid displaying the selectable dates MonthGrid { id: monthGrid locale: Qt.locale() Layout.fillWidth: true Layout.fillHeight: true font.pointSize: defaultPointSize // initialize with selected date of calendar property date gridDate: selectedDate month: gridDate.getMonth() year: gridDate.getFullYear() // add day property for simplyfication property int day: gridDate.getDate() // update year-select current index onYearChanged: yearList.updateCurrentIndex() function addMonths(amount) { let _date = gridDate _date.setMonth(_date.getMonth() + (amount)) gridDate = _date } delegate: Item { id: delegateItem Layout.fillHeight: true Layout.fillWidth: true // check if delegate is the selected day of the calendar property bool isSelectedDay: (model.year === selectedDate.getFullYear() && model.month === selectedDate.getMonth() && model.day === selectedDate.getDate( )) Rectangle { anchors.centerIn: parent // smaller side gets base length for highlight circle width: Math.min(parent.width, parent.height) height: width radius: width / 2 color: delegateItem.isSelectedDay ? accentColor : "transparent" Text { anchors.centerIn: parent opacity: model.month === monthGrid.month ? 1 : 0.25 color: delegateItem.isSelectedDay ? textColorOnAccent : fontColor text: model.day font: monthGrid.font } } } onClicked: { // if user selects date, apply it to selectedDate selectedDate = date } } RowLayout { Layout.fillWidth: true height: childrenRect.height spacing: 20 Row { Layout.fillWidth: true Text { font: monthGrid.font text: qsTr("Today") MouseArea { anchors.fill: parent // set selected date and grid view to "today" onClicked: { selectedDate = new Date() monthGrid.gridDate = selectedDate } } } } Row { spacing: 20 Text { horizontalAlignment: Text.AlignHCenter font: monthGrid.font text: qsTr("Cancel") MouseArea { anchors.fill: parent // emit cancel() signal of calendar onClicked: calendar.cancel() } } Text { horizontalAlignment: Text.AlignHCenter font: monthGrid.font text: qsTr("Confirm") MouseArea { anchors.fill: parent onClicked: { // apply day type before emitting confirm() signal applyDayType() calendar.confirm() } } } } } } enter: Transition { NumberAnimation { property: "opacity" from: 0.0 to: 1.0 duration: 180 } NumberAnimation { property: "scale" from: 0 to: 1 duration: 210 } } exit: Transition { NumberAnimation { property: "opacity" from: 1.0 to: 0.0 duration: 150 } SequentialAnimation { NumberAnimation { property: "scale" from: 1 to: 0.1 duration: 155 } NumberAnimation { property: "scale" from: 0.1 to: 1 duration: 1 } } } }
-
M mzimmers has marked this topic as solved on
-
@lemons thank you for sharing your component. I notice that it uses the Qt.labs version of the calendar. Have you given any thought to migrating to the "new" Qt Calendar?
@mzimmers I actually don't really use the component, I primarily wrote it for learning purpose ...
Below the changes that should make it work with Qt 6:
// remove versions to pick up Qt6 magic import QtQuick import QtQuick.Window import QtQuick.Controls import QtQuick.Layouts // remove Qt.labs.calendar
// ... MonthGrid { id: monthGrid // ... // change the onClicked to use formal parameters onClicked: function (date) { // if user selects date, apply it to selectedDate selectedDate = date } } // ...