Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。
本文中的CalendarWidget示例展示了QCalendarWidget的用法。在上文中(点击这里回顾>>)我们主要介绍了Window类定义的实现,本节就继续介绍,请继续关注我们哟~
QCalendarWidget一次显示一个日历月,并允许用户选择一个日期。日历由四个组件组成:一个允许用户更改显示月份的导航栏、一个网格、其中每个单元格表示一个月中的一天,以及两个显示星期名称和星期数字的标题。
点击获取Qt Widget组件下载
Qt技术交流群:166830288 欢迎一起进群讨论
接上文,我们将复选框和组合框连接到各种私有插槽,蓝色复选框中的第一个星期五和红色复选框中的May 1都连接到reformatCalendarPage(),该方法在日历切换月份时也被调用。
...
reformatHeaders();
reformatCalendarPage();
}
在createTextFormatsGroupBox()的末尾,我们调用私有槽来同步QCalendarWidget与其他小部件。
现在我们已经检查了四个create…GroupBox()函数,现在看一下其他私有函数和槽。
QComboBox *Window::createColorComboBox()
{
QComboBox *comboBox = new QComboBox;
comboBox->addItem(tr("Red"), QColor(Qt::red));
comboBox->addItem(tr("Blue"), QColor(Qt::blue));
comboBox->addItem(tr("Black"), QColor(Qt::black));
comboBox->addItem(tr("Magenta"), QColor(Qt::magenta));
return comboBox;
}
在createColorCombo()中,我们创建了一个组合框,并用标准颜色填充它。QComboBox::addItem()的第二个参数是一个存储用户数据的QVariant(在本例中是QColor对象)。
此函数用于设置工作日颜色和周末颜色组合框。
void Window::firstDayChanged(int index)
{
calendar->setFirstDayOfWeek(Qt::DayOfWeek(
firstDayCombo->itemData(index).toInt()));
}
当用户更改组合框的值上的星期开始时,firstDayChanged()将使用组合框新值的索引调用。我们使用itemData()检索与新的当前项关联的自定义数据项,并将其转换为Qt::DayOfWeek。
selectionModeChanged()、horizontalHeaderChanged()和verticalHeaderChanged()与firstDayChanged()非常相似,因此省略它们。
void Window::selectedDateChanged()
{
currentDateEdit->setDate(calendar->selectedDate());
}
selectedDateChanged()更新Current Date编辑器,以反映QCalendarWidget的当前状态。
void Window::minimumDateChanged(QDate date)
{
calendar->setMinimumDate(date);
maximumDateEdit->setDate(calendar->maximumDate());
}
当用户更改最小日期时,我们告诉QCalenderWidget。与此同时还更新了Maximum Date编辑器,因为如果新的最小日期晚于当前的最大日期,QCalendarWidget将自动调整其最大日期以避免矛盾状态。
void Window::maximumDateChanged(QDate date)
{
calendar->setMaximumDate(date);
minimumDateEdit->setDate(calendar->minimumDate());
}
maximumDateChanged()的实现类似于minimumDateChanged()。
void Window::weekdayFormatChanged()
{
QTextCharFormat format;
format.setForeground(qvariant_cast(
weekdayColorCombo->itemData(weekdayColorCombo->currentIndex())));
calendar->setWeekdayTextFormat(Qt::Monday, format);
calendar->setWeekdayTextFormat(Qt::Tuesday, format);
calendar->setWeekdayTextFormat(Qt::Wednesday, format);
calendar->setWeekdayTextFormat(Qt::Thursday, format);
calendar->setWeekdayTextFormat(Qt::Friday, format);
}
每个组合框项都有一个QColor对象作为与该项文本对应的用户数据,从组合框中获取颜色后,我们设置一周中每一天的文本格式。
日历中列的文本格式为QTextCharFormat,除了前景色外,它还允许我们指定各种字符格式信息。在这个例子中,我们只展示了可能性的一个子集。
void Window::weekendFormatChanged()
{
QTextCharFormat format;
format.setForeground(qvariant_cast(
weekendColorCombo->itemData(weekendColorCombo->currentIndex())));
calendar->setWeekdayTextFormat(Qt::Saturday, format);
calendar->setWeekdayTextFormat(Qt::Sunday, format);
}
weekendFormatChanged()与weekdayFormatChanged()相同,不同之处是它影响的是周六和周日,而不是周一到周五。
void Window::reformatHeaders()
{
QString text = headerTextFormatCombo->currentText();
QTextCharFormat format;
if (text == tr("Bold"))
format.setFontWeight(QFont::Bold);
else if (text == tr("Italic"))
format.setFontItalic(true);
else if (text == tr("Green"))
format.setForeground(Qt::green);
calendar->setHeaderTextFormat(format);
}
当用户更改标题的文本格式时,将调用reformatHeaders()插槽。我们比较标题文本格式组合框的当前文本,以确定应用哪种格式。(另一种选择是将QTextCharFormat值存储在组合框项旁边。)
void Window::reformatCalendarPage()
{
QTextCharFormat mayFirstFormat;
const QDate mayFirst(calendar->yearShown(), 5, 1);
QTextCharFormat firstFridayFormat;
QDate firstFriday(calendar->yearShown(), calendar->monthShown(), 1);
while (firstFriday.dayOfWeek() != Qt::Friday)
firstFriday = firstFriday.addDays(1);
if (firstFridayCheckBox->isChecked()) {
firstFridayFormat.setForeground(Qt::blue);
} else { // Revert to regular colour for this day of the week.
Qt::DayOfWeek dayOfWeek(static_cast(firstFriday.dayOfWeek()));
firstFridayFormat.setForeground(calendar->weekdayTextFormat(dayOfWeek).foreground());
}
calendar->setDateTextFormat(firstFriday, firstFridayFormat);
// When it is checked, "May First in Red" always takes precedence over "First Friday in Blue".
if (mayFirstCheckBox->isChecked()) {
mayFirstFormat.setForeground(Qt::red);
} else if (!firstFridayCheckBox->isChecked() || firstFriday != mayFirst) {
// We can now be certain we won't be resetting "May First in Red" when we restore
// may 1st's regular colour for this day of the week.
Qt::DayOfWeek dayOfWeek(static_cast(mayFirst.dayOfWeek()));
calendar->setDateTextFormat(mayFirst, calendar->weekdayTextFormat(dayOfWeek));
}
calendar->setDateTextFormat(mayFirst, mayFirstFormat);
}
在reformatCalendarPage()中,我们设置了该月的第一个星期五和当年的5月1日的文本格式,实际使用的文本格式取决于选中了哪些复选框以及工作日/周末的格式。
QCalendarWidget允许我们使用setDateTextFormat()设置单个日期的文本格式,我们选择在日历页面更改时设置日期格式-即显示新的月份-以及工作日/周末格式更改时设置日期格式,检查mayFirstCheckBox和firstDayCheckBox中的哪个被选中(如果有的话),并相应地设置文本格式。