📄 qcalendarwidget.cpp
字号:
void showMonth(int year, int month); void setDate(const QDate &d); void setMinimumDate(const QDate &date); void setMaximumDate(const QDate &date); void setRange(const QDate &min, const QDate &max); void setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat format); void setFirstColumnDay(Qt::DayOfWeek dayOfWeek); Qt::DayOfWeek firstColumnDay() const; bool weekNumbersShown() const; void setWeekNumbersShown(bool show); QTextCharFormat formatForCell(int row, int col) const; Qt::DayOfWeek dayOfWeekForColumn(int section) const; int columnForDayOfWeek(Qt::DayOfWeek day) const; QDate dateForCell(int row, int column) const; void cellForDate(const QDate &date, int *row, int *column) const; QString dayName(Qt::DayOfWeek day) const; void setView(QCalendarView *view) { m_view = view; } void internalUpdate(); int m_firstColumn; int m_firstRow; QDate date; QDate minimumDate; QDate maximumDate; int shownYear; int shownMonth; Qt::DayOfWeek m_firstDay; QCalendarWidget::HorizontalHeaderFormat horizontalHeaderFormat; bool m_weekNumbersShown; QMap<Qt::DayOfWeek, QTextCharFormat> m_dayFormats; QMap<QDate, QTextCharFormat> m_dateFormats; QTextCharFormat m_headerFormat; QCalendarView *m_view;};class QCalendarView : public QTableView{ Q_OBJECTpublic: QCalendarView(QWidget *parent = 0); void internalUpdate() { updateGeometries(); } void setReadOnly(bool enable); virtual void keyboardSearch(const QString & search) { Q_UNUSED(search) }signals: void changeDate(const QDate &date, bool changeMonth); void clicked(const QDate &date); void editingFinished();protected: QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers); void mouseDoubleClickEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void keyPressEvent(QKeyEvent *event); bool event(QEvent *event); QDate handleMouseEvent(QMouseEvent *event);public: bool readOnly;private: bool validDateClicked;#ifdef QT_KEYPAD_NAVIGATION QDate origDate;#endif};QCalendarModel::QCalendarModel(QObject *parent) : QAbstractTableModel(parent){ date = QDate::currentDate(); minimumDate = QDate::fromJulianDay(0); maximumDate = QDate(7999, 12, 31); shownYear = date.year(); shownMonth = date.month(); m_firstDay = Qt::Sunday; horizontalHeaderFormat = QCalendarWidget::ShortDayNames; m_weekNumbersShown = true; m_firstColumn = 1; m_firstRow = 1; m_view = 0;}Qt::DayOfWeek QCalendarModel::dayOfWeekForColumn(int column) const{ int col = column - m_firstColumn; if (col < 0 || col > 6) return Qt::Sunday; int day = m_firstDay + col; if (day > 7) day -= 7; return Qt::DayOfWeek(day);}int QCalendarModel::columnForDayOfWeek(Qt::DayOfWeek day) const{ if (day < 1 || day > 7) return -1; int column = (int)day - (int)m_firstDay; if (column < 0) column += 7; return column + m_firstColumn;}QDate QCalendarModel::dateForCell(int row, int column) const{ if (row < m_firstRow || row > m_firstRow + RowCount - 1 || column < m_firstColumn || column > m_firstColumn + ColumnCount - 1) return QDate(); QDate firstDate(shownYear, shownMonth, 15); if (!firstDate.isValid()) { return QDate(); } int columnForFirstOfShownMonth = columnForDayOfWeek(static_cast<Qt::DayOfWeek>(firstDate.dayOfWeek())); if (columnForFirstOfShownMonth - m_firstColumn < MinimumDayOffset) row -= 1; int daysInShownMonth = firstDate.daysInMonth(); int requestedDay = 7 * (row - m_firstRow) + column - columnForFirstOfShownMonth + 1; if (requestedDay > daysInShownMonth) { QDate nextMonth = firstDate.addMonths(1); if (!nextMonth.isValid()) { return QDate(); } return QDate(nextMonth.year(), nextMonth.month(), requestedDay - daysInShownMonth); } else if (requestedDay <= 0) { QDate previousMonth = firstDate.addMonths(-1); if (!previousMonth.isValid()) { return QDate(); } int daysInMonth = previousMonth.daysInMonth(); return QDate(previousMonth.year(), previousMonth.month(), daysInMonth + requestedDay); } return QDate(shownYear, shownMonth, requestedDay);}void QCalendarModel::cellForDate(const QDate &date, int *row, int *column) const{ int day = date.day(); QDate firstDate(shownYear, shownMonth, 15); int columnForFirstOfShownMonth = columnForDayOfWeek(static_cast<Qt::DayOfWeek>(firstDate.dayOfWeek())); int daysInShownMonth = firstDate.daysInMonth(); QDate previousMonth = firstDate.addMonths(-1); QDate nextMonth = firstDate.addMonths(1); if (date.year() == shownYear && date.month() == shownMonth) { *column = (day + columnForFirstOfShownMonth - m_firstColumn - 1) % 7; *row = (day + columnForFirstOfShownMonth - m_firstColumn - 1) / 7; } else if (previousMonth.isValid() && date.year() == previousMonth.year() && date.month() == previousMonth.month()) { int daysInMonth = previousMonth.daysInMonth(); *column = (day - daysInMonth + columnForFirstOfShownMonth - m_firstColumn - 1) % 7; *row = (day - daysInMonth + columnForFirstOfShownMonth - m_firstColumn - 1) / 7; if (*column < 0) { *column += 7; *row -= 1; } } else if (nextMonth.isValid() && date.year() == nextMonth.year() && date.month() == nextMonth.month()) { *column = (day + daysInShownMonth + columnForFirstOfShownMonth - m_firstColumn - 1) % 7; *row = (day + daysInShownMonth + columnForFirstOfShownMonth - m_firstColumn - 1) / 7; } else { *row = -1; *column = -1; return; } if (columnForFirstOfShownMonth - m_firstColumn < MinimumDayOffset) *row += 1; if (*row < 0 || *row > RowCount - 1 || *column < 0 || *column > ColumnCount - 1) { *row = -1; *column = -1; return; } *row += m_firstRow; *column += m_firstColumn;}QString QCalendarModel::dayName(Qt::DayOfWeek day) const{ switch (horizontalHeaderFormat) { case QCalendarWidget::SingleLetterDayNames: if (m_view->locale().language() == QLocale::Chinese) return m_view->locale().dayName(day, QLocale::ShortFormat).right(1); return m_view->locale().dayName(day, QLocale::ShortFormat).left(1); case QCalendarWidget::ShortDayNames: return m_view->locale().dayName(day, QLocale::ShortFormat); case QCalendarWidget::LongDayNames: return m_view->locale().dayName(day, QLocale::LongFormat); default: break; } return QString();}QTextCharFormat QCalendarModel::formatForCell(int row, int col) const{ QPalette pal; QPalette::ColorGroup cg = QPalette::Active; if (m_view) { pal = m_view->palette(); if (!m_view->isEnabled()) cg = QPalette::Disabled; else if (!m_view->isActiveWindow()) cg = QPalette::Inactive; } QTextCharFormat format; format.setFont(m_view->font()); bool header = (m_weekNumbersShown && col == HeaderColumn) || (horizontalHeaderFormat != QCalendarWidget::NoHorizontalHeader && row == HeaderRow); format.setBackground(pal.brush(cg, header ? QPalette::AlternateBase : QPalette::Base)); format.setForeground(pal.brush(cg, QPalette::Text)); if (header) { format.merge(m_headerFormat); } if (col >= m_firstColumn && col < m_firstColumn + ColumnCount) { Qt::DayOfWeek dayOfWeek = dayOfWeekForColumn(col); if (m_dayFormats.contains(dayOfWeek)) format.merge(m_dayFormats.value(dayOfWeek)); } if(!header) { QDate date = dateForCell(row, col); format.merge(m_dateFormats.value(date)); if(date < minimumDate || date > maximumDate) format.setBackground(pal.brush(cg, QPalette::Window)); if (shownMonth != date.month()) format.setForeground(pal.brush(QPalette::Disabled, QPalette::Text)); } return format;}QVariant QCalendarModel::data(const QModelIndex &index, int role) const{ if (role == Qt::TextAlignmentRole) return (int) Qt::AlignCenter; int row = index.row(); int column = index.column(); if(role == Qt::DisplayRole) { if (m_weekNumbersShown && column == HeaderColumn && row >= m_firstRow && row < m_firstRow + RowCount) { QDate date = dateForCell(row, columnForDayOfWeek(Qt::Monday)); if (date.isValid()) return date.weekNumber(); } if (horizontalHeaderFormat != QCalendarWidget::NoHorizontalHeader && row == HeaderRow && column >= m_firstColumn && column < m_firstColumn + ColumnCount) return dayName(dayOfWeekForColumn(column)); QDate date = dateForCell(row, column); if (date.isValid()) return date.day(); return QString(); } QTextCharFormat fmt = formatForCell(row, column); if (role == Qt::BackgroundColorRole) return fmt.background().color(); if (role == Qt::TextColorRole) return fmt.foreground().color(); if (role == Qt::FontRole) return fmt.font(); return QVariant();}Qt::ItemFlags QCalendarModel::flags(const QModelIndex &index) const{ QDate date = dateForCell(index.row(), index.column()); if (!date.isValid()) return QAbstractTableModel::flags(index); if (date < minimumDate) return 0; if (date > maximumDate) return 0; return QAbstractTableModel::flags(index);}void QCalendarModel::setDate(const QDate &d){ date = d; if (date < minimumDate) date = minimumDate; else if (date > maximumDate) date = maximumDate;}void QCalendarModel::showMonth(int year, int month){ if (shownYear == year && shownMonth == month) return; shownYear = year; shownMonth = month; internalUpdate();}void QCalendarModel::setMinimumDate(const QDate &d){ if (!d.isValid() || d == minimumDate) return; minimumDate = d; if (maximumDate < minimumDate) maximumDate = minimumDate; if (date < minimumDate) date = minimumDate; internalUpdate();}void QCalendarModel::setMaximumDate(const QDate &d){ if (!d.isValid() || d == maximumDate) return; maximumDate = d; if (minimumDate > maximumDate) minimumDate = maximumDate; if (date > maximumDate) date = maximumDate; internalUpdate();}void QCalendarModel::setRange(const QDate &min, const QDate &max){ minimumDate = min; maximumDate = max; if(minimumDate > maximumDate) qSwap(minimumDate, maximumDate); if (date < minimumDate) date = minimumDate; if (date > maximumDate) date = maximumDate; internalUpdate();}void QCalendarModel::internalUpdate(){ QModelIndex begin = index(0, 0); QModelIndex end = index(m_firstRow + RowCount - 1, m_firstColumn + ColumnCount - 1); emit dataChanged(begin, end); emit headerDataChanged(Qt::Vertical, 0, m_firstRow + RowCount - 1); emit headerDataChanged(Qt::Horizontal, 0, m_firstColumn + ColumnCount - 1);}void QCalendarModel::setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat format){ if (horizontalHeaderFormat == format) return; int oldFormat = horizontalHeaderFormat; horizontalHeaderFormat = format; if (oldFormat == QCalendarWidget::NoHorizontalHeader) { m_firstRow = 1; insertRow(0); } else if (horizontalHeaderFormat == QCalendarWidget::NoHorizontalHeader) { m_firstRow = 0; removeRow(0); } internalUpdate();}void QCalendarModel::setFirstColumnDay(Qt::DayOfWeek dayOfWeek){ if (m_firstDay == dayOfWeek) return; m_firstDay = dayOfWeek; internalUpdate();}Qt::DayOfWeek QCalendarModel::firstColumnDay() const{ return m_firstDay;}bool QCalendarModel::weekNumbersShown() const{ return m_weekNumbersShown;}void QCalendarModel::setWeekNumbersShown(bool show){ if (m_weekNumbersShown == show) return; m_weekNumbersShown = show; if (show) { m_firstColumn = 1; insertColumn(0); } else { m_firstColumn = 0; removeColumn(0); } internalUpdate();}QCalendarView::QCalendarView(QWidget *parent) : QTableView(parent), readOnly(false), validDateClicked(false){ setTabKeyNavigation(false); setShowGrid(false); verticalHeader()->setVisible(false); horizontalHeader()->setVisible(false); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);}QModelIndex QCalendarView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers){ QCalendarModel *calendarModel = ::qobject_cast<QCalendarModel *>(model()); if (!calendarModel) return QTableView::moveCursor(cursorAction, modifiers); if (readOnly) return currentIndex();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -