日历(QCalendarWidget)的使用及风格样式的设置 |
您所在的位置:网站首页 › 怎样把日历中的签到去掉 › 日历(QCalendarWidget)的使用及风格样式的设置 |
前言
之前项目中没涉及过日历控件(QCalendarWidget),一般我是用简单的日期编辑器代替,对它的印象只存在于QtDesigner中丑的不行的日历控件。这次我要写类似企业微信的日程(如下图)功能的东西,这个就必须用到日历了(此篇博客只介绍日历的写法)。 有两种方式实现:一是自己全部重写,二呢是,修改Qt自带的控件QCalendarWidget,难易程度我肯定选二个了,不过后续我想自己重写一个日历,这样自己更有自主权。 这次先把效果图放到前边吧,对比着代码看,更容易讲解。 代码部分参考大佬的博客QT之自定义日历-CSDN博客。 因为用的是Qt自带的日历控件,所以就不用操心基本功能(比如时间的管理),我们只需要将日历控件的外貌设置为我们想要的就行了。 导航栏的重写日历自带的导航栏真心丑,所以我将原始的导航栏隐藏起来自己又重新写了一个。左右按钮我没设置风格,因为写的是Demo,就犯懒了。 setNavigationBarVisible(false); void MyCalendarWidget::initTopWidget() { QWidget* topWidget = new QWidget(this); topWidget->setObjectName("CalendarTopWidget"); topWidget->setFixedHeight(40); topWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); QHBoxLayout* hboxLayout = new QHBoxLayout; hboxLayout->setContentsMargins(12, 0, 12, 0); hboxLayout->setSpacing(4); m_leftMonthBtn = new QPushButton(this); m_leftMonthBtn->setText(""); m_dataLabel = new QLabel(this); m_leftMonthBtn->setObjectName("CalendarLeftMonthBtn"); m_rightMonthBtn->setObjectName("CalendarRightMonthBtn"); m_dataLabel->setObjectName("CalendarDataLabel"); m_leftMonthBtn->setFixedSize(16, 16); m_rightMonthBtn->setFixedSize(16, 16); hboxLayout->addStretch(); hboxLayout->addWidget(m_leftMonthBtn); hboxLayout->addWidget(m_dataLabel); hboxLayout->addWidget(m_rightMonthBtn); hboxLayout->addStretch(); topWidget->setLayout(hboxLayout); QVBoxLayout *vBodyLayout = qobject_cast(layout()); vBodyLayout->insertWidget(0, topWidget); connect(m_leftMonthBtn,&QPushButton::clicked,this,&MyCalendarWidget::onbtnClicked); connect(m_rightMonthBtn,&QPushButton::clicked,this,&MyCalendarWidget::onbtnClicked); setDataLabelTimeText(selectedDate().year(), selectedDate().month()); } void MyCalendarWidget::onbtnClicked() { QPushButton *senderBtn = qobject_cast(sender()); if (senderBtn == m_leftMonthBtn) { showPreviousMonth(); } else if (senderBtn == m_rightMonthBtn) { showNextMonth(); } } 一些基础设置日历这这样首先设置为中文(setLocale),这为行表头(tHorizontalHeader)的名字的中英文做铺垫:中文就是周几,星期几,英文Monday Mon.之类。我还设置了单选和周六日的风格,这些东西不仅只是表面意思,还有其他的作用。 void MyCalendarWidget::initControl() { //layout()->setSizeConstraint(QLayout::SetFixedSize);//大小不随布局变化,我不需要 setLocale(QLocale(QLocale::Chinese));//设置中文 setNavigationBarVisible(false);//隐藏导航条 setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);//去掉列表头 setHorizontalHeaderFormat(QCalendarWidget::LongDayNames);//我想要星期几的行表头 setSelectionMode(QCalendarWidget::SingleSelection);//单选 //设置星期风格 QTextCharFormat format; format.setForeground(QColor(51, 51, 51)); format.setBackground(QColor(247,247,247)); format.setFontFamily("Microsoft YaHei"); format.setFontPointSize(9); format.setFontWeight(QFont::Medium); setWeekdayTextFormat(Qt::Saturday, format); setWeekdayTextFormat(Qt::Sunday, format); initTopWidget(); connect(this, &QCalendarWidget::currentPageChanged, [this](int year, int month){ setDataLabelTimeText(year, month); }); }先说我上面设置了日历是单选的,这个还有一个深层次的原因:我将选中的矩形改为圆形后,出现了一个问题就是,刚show出来后,在当天圆圈圈住后,前一天被矩形框住了,也就是有两个被选中了,前一天用的样式是原始的,而当天的是我新写的。我不知道什么原因造成的,所以只能将其设为单选解决此问题了。 我在上面曾说道,我通过代码只更改了周六日的风格,这是为什么呢?因为qss中我没找到将周六日红色字体改为正常的语句。然后还有一点指的注意的是:设置了weekday 的format,那么表头的format将无效。(If you also set a weekday text format, this format's foreground and background color will take precedence over the header's format.)所以这就造成我为了将周六日变为正常色,但是我就没办法将表头设为其他色了,有点遗憾。 我看了一点QCalendarWidget的源码,视图部分是QCalendarView控制的,它继承的QTableView;我之前以为QCalendarWidget的表头即为QHeaderView,后来发现不是,QCalendarView将表头隐藏,然后将第一行作为horizontalHeader,第一列作为verticalHeader,涉及到的代码有: enum { RowCount = 6, ColumnCount = 7, HeaderColumn = 0, HeaderRow = 0, MinimumDayOffset = 1 }; 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); } QCalendarWidget QAbstractItemView{ font-size:12px; font-family:Microsoft YaHei; font-weight:500; outline:0px; } QCalendarWidget QAbstractItemView:disabled{ color:#D3D3D3; } QCalendarWidget QAbstractItemView:enabled{ color:#333333; } QCalendarView#qt_calendar_calendarview { background-color: #F7F7F7; /*背景色*/ alternate-background-color:#F7F7F7; {/* 表头的背景颜色,为什么设置这个就有效,我不清楚*/ }为了更好地写qss,我学会了一个dump方法,这样可以看到控件的结构和objectName. ui->calendarWidget->dumpObjectTree();将打印出如下结果: QCalendarWidget::calendarWidget QVBoxLayout:: QCalendarModel:: QCalendarView::qt_calendar_calendarview QWidget::qt_scrollarea_viewport QWidget::qt_scrollarea_hcontainer QScrollBar:: QBoxLayout:: QWidget::qt_scrollarea_vcontainer QScrollBar:: QBoxLayout:: QStyledItemDelegate:: QHeaderView:: QWidget::qt_scrollarea_viewport QWidget::qt_scrollarea_hcontainer QScrollBar:: QBoxLayout:: QWidget::qt_scrollarea_vcontainer QScrollBar:: QBoxLayout:: QItemSelectionModel:: QHeaderView:: QWidget::qt_scrollarea_viewport QWidget::qt_scrollarea_hcontainer QScrollBar:: QBoxLayout:: QWidget::qt_scrollarea_vcontainer QScrollBar:: QBoxLayout:: QItemSelectionModel:: QTableCornerButton:: QItemSelectionModel:: QWidget::qt_calendar_navigationbar QPrevNextCalButton::qt_calendar_prevmonth QPrevNextCalButton::qt_calendar_nextmonth QToolButton::qt_calendar_monthbutton QMenu:: QAction:: QAction:: QAction:: QAction:: QAction:: QAction:: QAction:: QAction:: QAction:: QAction:: QAction:: QAction:: QAction:: QToolButton::qt_calendar_yearbutton QSpinBox::qt_calendar_yearedit QLineEdit::qt_spinbox_lineedit QWidgetLineControl:: QValidator::qt_spinboxvalidator QHBoxLayout:: QCalendarDelegate:: QCalendarTextNavigator:: QProxyStyle:: QWidget::CalendarTopWidget QHBoxLayout:: QPushButton::CalendarLeftMonthBtn QLabel::CalendarDataLabel QPushButton::CalendarRightMonthBtn 结束语好了,下班了,就这样了,周末愉快。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |