import QtQuick import QtQuick.Controls import QtQuick.Layouts // Простой календарь: шапка (месяц/год, ←/→), сетка дней. // Клик по дню → onDaySelected("YYYY-MM-DD"). Item { id: cal signal daySelected(string dateStr) property date currentMonth: new Date() readonly property int year: currentMonth.getFullYear() readonly property int month: currentMonth.getMonth() // 0..11 function fmtDate(d) { function pad(n) { return n < 10 ? "0" + n : "" + n } return d.getFullYear() + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate()) } function gridModel() { const first = new Date(year, month, 1) const startDow = first.getDay() // 0=вс const daysInMonth = new Date(year, month + 1, 0).getDate() const list = [] for (let i = 0; i < startDow; ++i) list.push(0) for (let d = 1; d <= daysInMonth; ++d) list.push(d) return list } ColumnLayout { anchors.fill: parent spacing: 2 RowLayout { Layout.fillWidth: true ToolButton { text: "<" onClicked: cal.currentMonth = new Date(year, month - 1, 1) } Label { Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter font.bold: true text: Qt.locale().monthName(month, Locale.LongFormat) + " " + year } ToolButton { text: ">" onClicked: cal.currentMonth = new Date(year, month + 1, 1) } } RowLayout { Layout.fillWidth: true Repeater { model: ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"] Label { Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter font.pixelSize: 10 color: "#888" text: modelData } } } Grid { Layout.fillWidth: true Layout.fillHeight: true columns: 7 rowSpacing: 1 columnSpacing: 1 Repeater { model: cal.gridModel() delegate: Rectangle { required property int modelData width: cal.width / 7 - 2 height: cal.height / 10 - 1 radius: 3 color: modelData > 0 && modelData === now.day ? "#dbeafe" : (modelData > 0 ? "#ffffff" : "transparent") readonly property var now: { const t = new Date() return { day: t.getDate(), month: t.getMonth(), year: t.getFullYear() } } Label { anchors.centerIn: parent visible: modelData > 0 text: modelData font.pixelSize: 11 color: modelData > 0 ? "#222" : "#ddd" } MouseArea { anchors.fill: parent visible: modelData > 0 onClicked: { const d = new Date(cal.year, cal.month, modelData) cal.daySelected(fmtDate(d)) } } } } } } }