qcalendarwidget.cpp
来自「QT 开发环境里面一个很重要的文件」· C++ 代码 · 共 2,019 行 · 第 1/4 页
CPP
2,019 行
}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(); QModelIndex index = currentIndex(); QDate currentDate = static_cast<QCalendarModel*>(model())->dateForCell(index.row(), index.column()); switch (cursorAction) { case QAbstractItemView::MoveUp: currentDate = currentDate.addDays(-7); break; case QAbstractItemView::MoveDown: currentDate = currentDate.addDays(7); break; case QAbstractItemView::MoveLeft: currentDate = currentDate.addDays(-1); break; case QAbstractItemView::MoveRight: currentDate = currentDate.addDays(1); break; case QAbstractItemView::MoveHome: currentDate = QDate(currentDate.year(), currentDate.month(), 1); break; case QAbstractItemView::MoveEnd: currentDate = QDate(currentDate.year(), currentDate.month(), currentDate.daysInMonth()); break; case QAbstractItemView::MovePageUp: currentDate = currentDate.addMonths(-1); break; case QAbstractItemView::MovePageDown: currentDate = currentDate.addMonths(1); break; case QAbstractItemView::MoveNext: case QAbstractItemView::MovePrevious: return currentIndex(); default: break; } emit changeDate(currentDate, true); return currentIndex();}void QCalendarView::keyPressEvent(QKeyEvent *event){ if (!readOnly) { switch (event->key()) { case Qt::Key_Return: case Qt::Key_Enter: case Qt::Key_Space: case Qt::Key_Select: emit editingFinished(); break; default: break; } } QTableView::keyPressEvent(event);}bool QCalendarView::event(QEvent *event){ return QTableView::event(event);}QDate QCalendarView::handleMouseEvent(QMouseEvent *event){ QCalendarModel *calendarModel = ::qobject_cast<QCalendarModel *>(model()); if (!calendarModel) return QDate(); QPoint pos = event->pos(); QModelIndex index = indexAt(pos); QDate date = calendarModel->dateForCell(index.row(), index.column()); if (date.isValid() && date >= calendarModel->minimumDate && date <= calendarModel->maximumDate) { return date; } return QDate();}void QCalendarView::mouseDoubleClickEvent(QMouseEvent *event){ QCalendarModel *calendarModel = ::qobject_cast<QCalendarModel *>(model()); if (!calendarModel) { QTableView::mouseDoubleClickEvent(event); return; } if (readOnly) return; QDate date = handleMouseEvent(event); validDateClicked = false; if (date == calendarModel->date && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)) { emit editingFinished(); }}void QCalendarView::mousePressEvent(QMouseEvent *event){ QCalendarModel *calendarModel = ::qobject_cast<QCalendarModel *>(model()); if (!calendarModel) { QTableView::mousePressEvent(event); return; } if (readOnly) return; if (event->button() != Qt::LeftButton) return; QDate date = handleMouseEvent(event); if (date.isValid()) { validDateClicked = true; int row = -1, col = -1; static_cast<QCalendarModel *>(model())->cellForDate(date, &row, &col); if (row != -1 && col != -1) { selectionModel()->setCurrentIndex(model()->index(row, col), QItemSelectionModel::NoUpdate); } } else { validDateClicked = false; event->ignore(); }}void QCalendarView::mouseMoveEvent(QMouseEvent *event){ QCalendarModel *calendarModel = ::qobject_cast<QCalendarModel *>(model()); if (!calendarModel) { QTableView::mouseMoveEvent(event); return; } if (readOnly) return; if (validDateClicked) { QDate date = handleMouseEvent(event); if (date.isValid()) { int row = -1, col = -1; static_cast<QCalendarModel *>(model())->cellForDate(date, &row, &col); if (row != -1 && col != -1) { selectionModel()->setCurrentIndex(model()->index(row, col), QItemSelectionModel::NoUpdate); } } } else { event->ignore(); }}void QCalendarView::mouseReleaseEvent(QMouseEvent *event){ QCalendarModel *calendarModel = ::qobject_cast<QCalendarModel *>(model()); if (!calendarModel) { QTableView::mouseReleaseEvent(event); return; } if (event->button() != Qt::LeftButton) return; if (readOnly) return; if (validDateClicked) { QDate date = handleMouseEvent(event); if (date.isValid()) { emit changeDate(date, true); emit clicked(date); if (style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)) emit editingFinished(); } validDateClicked = false; } else { event->ignore(); }}class QCalendarDelegate : public QItemDelegate{ Q_OBJECTpublic: QCalendarDelegate(QCalendarWidgetPrivate *w, QObject *parent = 0) : QItemDelegate(parent), calendarWidgetPrivate(w) { } virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const;private: QCalendarWidgetPrivate *calendarWidgetPrivate; mutable QStyleOptionViewItem storedOption;};//Private tool button classclass QCalToolButton: public QToolButton{public: QCalToolButton(QWidget * parent) :QToolButton(parent), hover(false) ,oldState(false) { }private: bool hover, oldState;protected: void enterEvent(QEvent * e) { hover = true; QToolButton::enterEvent(e); } void leaveEvent(QEvent * e) { hover = false; QToolButton::leaveEvent(e); } void mousePressEvent(QMouseEvent * e) { hover = true; QToolButton::mousePressEvent(e); } void mouseReleaseEvent(QMouseEvent * e) { hover = true; QToolButton::mouseReleaseEvent(e); } void paintEvent(QPaintEvent *e) { QPalette toolPalette = parentWidget()->palette(); bool newState = (menu()) ? menu()->isVisible():isDown();#ifndef Q_WS_MAC if (newState || hover) //act as normal button setPalette(toolPalette); else { //set the highlight color for button text toolPalette.setColor(QPalette::ButtonText, toolPalette.color(QPalette::HighlightedText)); setPalette(toolPalette); }#endif if (newState != oldState) { //update the hover if the button is released hover = oldState ? false : hover; oldState = newState; } QToolButton::paintEvent(e); }};class QCalendarWidgetPrivate : public QWidgetPrivate{ Q_DECLARE_PUBLIC(QCalendarWidget)public: QCalendarWidgetPrivate(); void showMonth(int year, int month); void update(); void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const; void _q_slotChangeDate(const QDate &date, bool changeMonth); void _q_editingFinished(); void _q_monthChanged(QAction*); void _q_prevMonthClicked(); void _q_nextMonthClicked(); void _q_yearEditingFinished(); void _q_yearClicked(); void createHeader(QWidget *widget); void updateMonthMenu(); void updateHeader(); void updateCurrentPage(QDate &newDate); inline QDate getCurrentDate(); QCalendarModel *m_model; QCalendarView *m_view; QCalendarDelegate *m_delegate; QItemSelectionModel *m_selection; QToolButton *nextMonth; QToolButton *prevMonth; QCalToolButton *monthButton; QMenu *monthMenu; QMap<int, QAction *> monthToAction; QCalToolButton *yearButton; QSpinBox *yearEdit; QWidget *headerBackground; QSpacerItem *spaceHolder; bool headerVisible;};void QCalendarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{ QDate date = calendarWidgetPrivate->m_model->dateForCell(index.row(), index.column()); if (date.isValid()) { storedOption = option; QRect rect = option.rect; calendarWidgetPrivate->paintCell(painter, rect, date); } else { QItemDelegate::paint(painter, option, index); }}void QCalendarDelegate::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const{ storedOption.rect = rect; int row = -1; int col = -1; calendarWidgetPrivate->m_model->cellForDate(date, &row, &col); QModelIndex idx = calendarWidgetPrivate->m_model->index(row, col); QItemDelegate::paint(painter, storedOption, idx);}QCalendarWidgetPrivate::QCalendarWidgetPrivate() : QWidgetPrivate(){ m_model = 0; m_view = 0; m_delegate = 0; m_selection = 0; headerVisible = true;}void QCalendarWidgetPrivate::createHeader(QWidget *widget){ Q_Q(QCalendarWidget); headerBackground = new QWidget(widget); headerBackground->setAutoFillBackground(true); headerBackground->setBackgroundRole(QPalette::Highlight); prevMonth = new QToolButton(headerBackground); nextMonth = new QToolButton(headerBackground); prevMonth->setAutoRaise(true); nextMonth->setAutoRaise(true); prevMonth->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); nextMonth->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); nextMonth->setAutoRaise(true); prevMonth->setIcon(q->style()->standardPixmap(QStyle::SP_ArrowLeft)); nextMonth->setIcon(q->style()->standardPixmap(QStyle::SP_ArrowRight)); prevMonth->setAutoRepeat(true); nextMonth->setAutoRepeat(true); prevMonth->setFocusProxy(m_view); nextMonth->setFocusProxy(m_view); monthButton = new QCalToolButton(headerBackground); monthButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); monthButton->setAutoRaise(true); monthButton->setPopupMode(QToolButton::InstantPopup); monthMenu = new QMenu(monthButton); for (int i = 1; i <= 12; i++) { QString monthName(QDate::longMonthName(i)); QAction *act = monthMenu->addAction(monthName); act->setData(i); monthToAction[i] = act; } monthButton->setMenu(monthMenu); yearButton = new QCalToolButton(headerBackground); yearButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); yearButton->setAutoRaise(true); yearEdit = new QSpinBox(headerBackground); QFont font = q->font(); font.setBold(true); monthButton->setFont(font); yearButton->setFont(font); yearEdit->setFrame(false); yearEdit->setMinimum(m_model->minimumDate.year()); yearEdit->setMaximum(m_model->maximumDate.year()); yearEdit->hide(); spaceHolder = new QSpacerItem(0,0); QHBoxLayout *headerLayout = new QHBoxLayout; headerLayout->setMargin(0); headerLayout->setSpacing(0); headerLayout->addWidget(prevMonth); headerLayout->insertStretch(headerLayout->count()); headerLayout->addWidget(monthButton); headerLayout->addItem(spaceHolder); headerLayout->addWidget(yearButton); headerLayout->insertStretch(headerLayout->count()); headerLayout->addWidget(nextMonth); headerBackground->setLayout(headerLayout); yearEdit->setFocusPolicy(Qt::StrongFocus); prevMonth->setFocusPolicy(Qt::StrongFocus); nextMonth->setFocusPolicy(Qt::StrongFocus); //set names for the header controls. prevMonth->setObjectName("qt_calendar_prevmonth"); nextMonth->setObjectName("qt_calendar_nextmonth"); monthButton->setObjectName("qt_calendar_monthbutton"); yearButton->setObjectName("qt_calendar_yearbutton"); yearEdit->setObjectName("qt_calendar_yearedit"); updateMonthMenu(); showMonth(m_model->date.year(),m_model->date.month());}void QCalendarWidgetPrivate::updateMonthMenu(){ int beg = 1, end = 12; bool prevEnabled = true; bool nextEnabled = true; if (m_model->shownYear == m_model->minimumDate.year()) { beg = m_model->minimumDate.month(); if (m_model->shownMonth == m_model->minimumDate.month()) prevEnabled = false; } if (m_model->shownYear == m_model->maximumDate.year()) { end = m_model->maximumDate.month(); if (m_model->shownMonth == m_model->maximumDate.month()) nextEnabled = false; } prevMonth->setEnabled(prevEnabled); nextMonth->setEnabled(nextEnabled); for (int i = 1; i <= 12; i++) { bool monthEnabled = true; if (i < beg || i > end) monthEnabled = false; monthToAction[i]->setEnabled(monthEnabled); }}void QCalendarWidgetPrivate::updateCurrentPage(QDate &newDate){ Q_Q(QCalendarWidget); QDate minDate = q->minimumDate(); QDate maxDate = q->maximumDate(); if (minDate.isValid()&& minDate.daysTo(newDate) < 0) newDate = minDate; if (maxDate.isValid()&& maxDate.daysTo(newDate) > 0) newDate = maxDate; showMonth(newDate.year(), newDate.month()); int row = -1, col = -1; m_model->cellForDate(newDate, &row, &col); if (row != -1 && col != -1) { m_view->selectionModel()->setCurrentIndex(m_model->index(row, col), QItemSelectionModel::NoUpdate); }}void QCalendarWidgetPrivate::_q_monthChanged(QAction *act){ monthButton->setText(act->text()); QDate currentDate = getCurrentDate(); QDate newDate = currentDate.addMonths(act->data().toInt()-currentDate.month()); updateCurrentPage(newDate);}QDate QCalendarWidgetPrivate::getCurrentDate(){ QModelIndex index = m_view->currentIndex(); return m_model->dateForCell(index.row(), index.column());}void QCalendarWidgetPrivate::_q_prevMonthClicked(){ QDate currentDate = getCurrentDate().addMonths(-1); updateCurrentPage(currentDate);}void QCalendarWidgetPrivate::_q_nextMonthClicked(){ QDate currentDate = getCurrentDate().addMonths(1); updateCurrentPage(currentDate);}void QCalendarWidgetPrivate::_q_yearEditingFinished(){ yearButton->setText(yearEdit->text()); yearEdit->hide(); spaceHolder->changeSize(0, 0); yearButton->show(); QDate currentDate(yearEdit->text().toInt(), getCurrentDate().month(), getCurrentDate().day()); updateCurrentPage(currentDate);}void QCalendarWidgetPrivate::_q_yearClicked(){ //show the spinbox on top of the button yearEdit->setGeometry(yearButton->x(), yearButton->y(), yearEdit->sizeHint().width(), yearButton->height()); spaceHolder->changeSize(yearButton->width(), 0); yearButton->hide(); yearEdit->show(); yearEdit->raise(); yearEdit->selectAll(); yearEdit->setFocus(Qt::MouseFocusReason);}void QCalendarWidgetPrivate::showMonth(int year, int month){ if (m_model->shownYear == year && m_model->shownMonth == month) return;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?