太长不看版
Qt日历中使用setWeekdayTextFormat
修改周末文字颜色和setHeaderTextFormat
修改表头文字颜色发生冲突,通过找到每个周末日期来修改文字颜色。效果图和代码见文末
在Qt中用到了QCalendarWidget,根据设计给出的设计图,需对其进行修改,搜索一下有很多可以参考的方法,比如这个就比较完善了,但还需要进行一些修改
修改周末的颜色
把周末的红色去掉,改成和周一-周五一致,可调用setWeekdayTextFormat(Qt::DayOfWeek dayOfWeek, const QTextCharFormat &format)
进行设置
QCalendarWidget* calendar = new QCalendarWidget(this);
QTextCharFormat weekendFormat;
weekendFormat.setForeground(QBrush(Qt::gray));
calendar->setWeekdayTextFormat(Qt::Saturday, weekendFormat);
calendar->setWeekdayTextFormat(Qt::Sunday, weekendFormat);
这样一顿操作之后获得的日历如下图所示
修改表头周x的颜色
但根据设计图,需要在保持【2】区域白底灰字的前提下,将【1】区域改为灰底白字,翻阅QCalendarWidget
的函数,发现有一个setHeaderTextFormat(const QTextCharFormat &format)
但尝试之后发现会出现以下情况:
可以发现表头周末的文字颜色并没有改变,仔细看以下Qt文档可以发现
void QCalendarWidget::setHeaderTextFormat(const QTextCharFormat &format)
Sets the text char format for rendering the header to format. If you also set a weekday text format, this format’s foreground and background color will take precedence over the header’s format. The other formatting information will still be decided by the header’s format.
因为在前面对周末设置了weekday text format,所以在这里表头样式对周末不起作用。
搜索一番找到一个可能有参考意义的方案,不过这个是修改表头的背景颜色,根据这个思路去翻了一下QCalendarModel
中formatForCell(int, int)
的源码,发现是长这样的:
format.setBackground(pal.brush(cg, header ? QPalette::AlternateBase : QPalette::Base));
format.setForeground(pal.brush(cg, QPalette::Text));
佛了,为什么背景知道要区分是不是表头,前景色就不管了
到这里好像没有什么直接修改表头文字颜色的好办法了,重写QCalendarWidget类也比较麻烦,还不如把源码贴到项目里改个名。
最后的解决办法
不过办法总是有的,就是笨一点,这里用到了setDateTextFormat(QDate , QTextCharFormat)
函数,既然有冲突那就不设置特定星期x的样式,而是设置好表头样式,再一天天的设置每个属于周末的日期的文字样式,代码如下
// slot
void MyWidget::UpdateCldColor(int y, int m) {
QTextCharFormat dateFormat;
dateFormat.setForeground(QBrush(Qt::gray));
int d = 1;
QDate curdate = QDate(y, m, d);
int curday = curdate.dayOfWeek();
int curmonth = curdate.month();
// 找到第一个星期六
while (curdate.isValid() && curday != 6) {
if (curday == 7) {
calendar->setDateTextFormat(curdate, dateFormat);
}
curdate = curdate.addDays(1);
curday = curdate.dayOfWeek();
}
// 给每个周末设颜色
while (curdate.isValid() && curmonth == m) {
for (int i = 0; i < 2; i++) {
if (curmonth != m) break;
calendar->setDateTextFormat(curdate, dateFormat);
curdate = curdate.addDays(1);
curday = curdate.dayOfWeek();
curmonth = curdate.month();
}
curdate = curdate.addDays(5);
curday = curdate.dayOfWeek();
curmonth = curdate.month();
}
}
// 对calendar设置
calendar = new QCalendarWidget(this);
// 设置表头Mon - Fri颜色
QTextCharFormat fmt;
fmt.setForeground(QBrush(Qt::white));
fmt.setBackground(QBrush(Qt::gray));
calendar->setHeaderTextFormat(fmt);
//设置表头Sat - Sun颜色
QTextCharFormat weekendFormat;
weekendFormat.setForeground(QBrush(Qt::white));
calendar->setWeekdayTextFormat(Qt::Saturday, weekendFormat);
calendar->setWeekdayTextFormat(Qt::Sunday, weekendFormat);
// 出现时先调用一次
UpdateCldColor(calendar->monthShown(), calendar->yearShown());
// 每次翻页重新绘制
connect(calendar, SIGNAL(currentPageChanged(int, int)), this, SLOT(UpdateCldColor(int, int)));
最终效果如下
完成!如果有其他更好的办法欢迎指出~