界面开发框架Qt新手入门指南 - 使用Calendar组件创建日历(一)

news/2024/12/3 7:30:45/

Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。

本文中的CalendarWidget示例展示了QCalendarWidget的用法。

点击获取Qt Widget组件下载

QCalendarWidget一次显示一个日历月,并允许用户选择一个日期。日历由四个组件组成:一个允许用户更改显示月份的导航栏、一个网格,其中每个单元格表示一个月中的一天,以及两个显示星期名称和星期数字的标题。

Calendar Widget示例显示一个QCalendarWidget,并允许用户使用QComboBoxes、QCheckBoxes和QDateEdits配置其外观和操作,此外,用户可以影响单个日期和标题的格式。

QCalendarWidget的属性总结如下:

  • selectedDate:当前选择的日期。
  • minimumDate:可以选择的最早日期。
  • maximumDate:可以选择的最晚日期。
  • firstDayOfWeek:显示为一周的第一天的日期(通常是星期日或星期一)。
  • gridVisible:是否显示网格。
  • selectionMode:用户是否可以选择日期。
  • horizontalHeaderFormat:水平标题中日期名称的格式(例如,"M", "Mon"或"Monday")。
  • verticalHeaderFormat:垂直页眉的格式。
  • navigationBarVisible:是否显示日历小部件顶部的导航栏。

本示例包含一个类Window,它创建并布局QCalendarWidget和其他让用户配置QCalendarWidget的小部件。

窗口类定义

下面是Window类的定义:

class Window : public QWidget
{
Q_OBJECTpublic:
Window(QWidget *parent = nullptr);private slots:
void localeChanged(int index);
void firstDayChanged(int index);
void selectionModeChanged(int index);
void horizontalHeaderChanged(int index);
void verticalHeaderChanged(int index);
void selectedDateChanged();
void minimumDateChanged(QDate date);
void maximumDateChanged(QDate date);
void weekdayFormatChanged();
void weekendFormatChanged();
void reformatHeaders();
void reformatCalendarPage();private:
void createPreviewGroupBox();
void createGeneralOptionsGroupBox();
void createDatesGroupBox();
void createTextFormatsGroupBox();
QComboBox *createColorComboBox();QGroupBox *previewGroupBox;
QGridLayout *previewLayout;
QCalendarWidget *calendar;QGroupBox *generalOptionsGroupBox;
QLabel *localeLabel;
QLabel *firstDayLabel;
...
QCheckBox *mayFirstCheckBox;
};

与表示自包含窗口的类一样,大多数API都是私有的。当我们在执行过程中偶然发现私人成员时,将对其进行审查。

窗口类实现

现在让我们回顾一下类的实现,从构造函数开始:

Window::Window(QWidget *parent)
: QWidget(parent)
{
createPreviewGroupBox();
createGeneralOptionsGroupBox();
createDatesGroupBox();
createTextFormatsGroupBox();QGridLayout *layout = new QGridLayout;
layout->addWidget(previewGroupBox, 0, 0);
layout->addWidget(generalOptionsGroupBox, 0, 1);
layout->addWidget(datesGroupBox, 1, 0);
layout->addWidget(textFormatsGroupBox, 1, 1);
layout->setSizeConstraint(QLayout::SetFixedSize);
setLayout(layout);previewLayout->setRowMinimumHeight(0, calendar->sizeHint().height());
previewLayout->setColumnMinimumWidth(0, calendar->sizeHint().width());setWindowTitle(tr("Calendar Widget"));
}

我们首先使用四个私有的create…GroupBox()函数创建四个qgroupbox及其子部件(包括QCalendarWidget),如下所述,然后在QGridLayout中安排组框。

我们将网格布局的调整大小策略设置为QLayout::SetFixedSize,以防止用户调整窗口大小。在这种模式下,窗口的大小由QGridLayout根据其内容小部件的大小提示自动设置。

为了确保在每次更改QCalendarWidget的属性(例如,隐藏导航栏、垂直标题或网格)时不会自动调整窗口的大小,我们将第0行的最小高度和第0列的最小宽度设置为QCalendarWidget的初始大小。

让我们来看看createPreviewGroupBox()函数:

void Window::createPreviewGroupBox()
{
previewGroupBox = new QGroupBox(tr("Preview"));calendar = new QCalendarWidget;
calendar->setMinimumDate(QDate(1900, 1, 1));
calendar->setMaximumDate(QDate(3000, 1, 1));
calendar->setGridVisible(true);connect(calendar, &QCalendarWidget::currentPageChanged,
this, &Window::reformatCalendarPage);previewLayout = new QGridLayout;
previewLayout->addWidget(calendar, 0, 0, Qt::AlignCenter);
previewGroupBox->setLayout(previewLayout);
}

Preview组框只包含一个小部件:QCalendarWidget,我们设置它,将它的currentPageChanged()信号连接到reformatCalendarPage()插槽,以确保每个新页面都获得用户指定的格式。

createGeneralOptionsGroupBox()函数有点大,并且以相同的方式设置了几个小部件。我们将在这里查看它的部分实现,并跳过其余部分:

void Window::createGeneralOptionsGroupBox()
{
generalOptionsGroupBox = new QGroupBox(tr("General Options"));localeCombo = new QComboBox;
int curLocaleIndex = -1;
int index = 0;
for (int _lang = QLocale::C; _lang <= QLocale::LastLanguage; ++_lang) {
QLocale::Language lang = static_cast<QLocale::Language>(_lang);
const auto locales =
QLocale::matchingLocales(lang, QLocale::AnyScript, QLocale::AnyTerritory);
for (auto loc : locales) {
QString label = QLocale::languageToString(lang);
auto territory = loc.territory();
label += QLatin1Char('/');
label += QLocale::territoryToString(territory);
if (locale().language() == lang && locale().territory() == territory)
curLocaleIndex = index;
localeCombo->addItem(label, loc);
++index;
}
}
if (curLocaleIndex != -1)
localeCombo->setCurrentIndex(curLocaleIndex);
localeLabel = new QLabel(tr("&Locale"));
localeLabel->setBuddy(localeCombo);firstDayCombo = new QComboBox;
firstDayCombo->addItem(tr("Sunday"), Qt::Sunday);
firstDayCombo->addItem(tr("Monday"), Qt::Monday);
firstDayCombo->addItem(tr("Tuesday"), Qt::Tuesday);
firstDayCombo->addItem(tr("Wednesday"), Qt::Wednesday);
firstDayCombo->addItem(tr("Thursday"), Qt::Thursday);
firstDayCombo->addItem(tr("Friday"), Qt::Friday);
firstDayCombo->addItem(tr("Saturday"), Qt::Saturday);firstDayLabel = new QLabel(tr("Wee&k starts on:"));
firstDayLabel->setBuddy(firstDayCombo);
...

我们从组合框上的周开始设置开始,此组合框控制哪一天应显示为一周的第一天。

QComboBox类允许我们将用户数据作为QVariant附加到每个项目,稍后可以使用QComboBox的itemData()函数检索数据。QVariant不直接支持Qt::DayOfWeek数据类型,但它支持int, c++会很乐意将任何enum值转换为int。

...
connect(localeCombo, &QComboBox::currentIndexChanged,
this, &Window::localeChanged);
connect(firstDayCombo, &QComboBox::currentIndexChanged,
this, &Window::firstDayChanged);
connect(selectionModeCombo, &QComboBox::currentIndexChanged,
this, &Window::selectionModeChanged);
connect(gridCheckBox, &QCheckBox::toggled,
calendar, &QCalendarWidget::setGridVisible);
connect(navigationCheckBox, &QCheckBox::toggled,
calendar, &QCalendarWidget::setNavigationBarVisible);
connect(horizontalHeaderCombo, &QComboBox::currentIndexChanged,
this, &Window::horizontalHeaderChanged);
connect(verticalHeaderCombo, &QComboBox::currentIndexChanged,
this, &Window::verticalHeaderChanged);
...

在创建了小部件之后,我们连接信号和插槽,将组合框连接到Window的私有槽或QComboBox提供的公共槽。

...
firstDayChanged(firstDayCombo->currentIndex());
selectionModeChanged(selectionModeCombo->currentIndex());
horizontalHeaderChanged(horizontalHeaderCombo->currentIndex());
verticalHeaderChanged(verticalHeaderCombo->currentIndex());
}

在函数的最后,我们调用更新日历的槽,以确保QCalendarWidget在启动时与其他小部件同步。

在下文中,我们将继续介绍更多实现窗口类的函数,欢迎持续关注哦~

 


http://www.ppmy.cn/news/380032.html

相关文章

解决帝国时代 之 罗马复兴 不能加入游戏的问题

在我们玩帝国时代时,在加入网络游戏时,尤其是在浩方对战平台上运行游戏时,经常有"不能加入该游戏"的错误产生这个原因一般都是因为你装的DirectPlay版本的原因,我的是9.0所以不行. 你不必重新安装8.0 因为Windows 在装入dll 时&#xff0c;总是先搜索exe所在的当…

罗马复兴各民族兵种详细参数——希腊篇

序号兵种攻击力防御力盾牌射程生命值依赖建筑1刀斧手540602 50 2剑士741602 60 3投石兵230224225 4木弓手3106 5335 5十字弓手      6战车射手      7战象射手      8侦察骑兵3406  68 9双头马      10重骑兵104161 172 11战象      …

罗马复兴各民族兵种详细参数——亚述篇

序号兵种攻击力防御力盾牌射程生命值依赖建筑1刀斧手5704 50 2长剑手11724 80 3投石兵 4木弓手304 5335 5十字弓手 6战车射手404 7370 7黑骑70427360 8战象射手 9侦察骑兵3704 60 10单头马7704 100 11金骑兵127341 180 12战象 13骆驼骑兵6704 125 14百…

欧洲文艺复兴时期,中国在干啥?

公元476年&#xff0c;罗马雇佣兵领袖日耳曼人奥多亚克废黜西罗马最后一个皇帝&#xff0c;西罗马遂告灭亡。西罗马帝国灭亡后&#xff0c;欧洲进入了近一千年的中世纪&#xff0c;地处欧洲的西方文明在经过古希腊文明和古罗马文明两次高光时段后&#xff0c;进入漫长的黑暗时期…

罗马复兴各民族兵种详细参数——埃及篇

序号兵种攻击力防御力盾牌射程生命值依赖建筑1刀斧手5706 5&#xff0b;350 3投石兵2202   4木弓手3106 5335 5十字弓手5106 7345 6战车射手4106 73106 7战象射手5106 73600 8侦察骑兵3706  68 9双头马9726  182 10战象1506  600 11骆驼骑兵6706  143 …

罗马复兴各民族兵种详细参数——克里特篇

序号兵种攻击力防御力盾牌射程生命值1刀斧手570603 502长剑手1172603 803投石兵2302342254木弓手3106 53355十字弓手5106 75456战车射手 7黑骑 8战象射手 9侦察骑兵3706 6810单头马 11骑兵8706 17212战象 13骆驼骑兵6706 14314百夫长3078603 16015黄金投…

罗马复兴各民族兵种详细参数——西台篇

序号 兵种 攻击力 防御力 盾牌 射程 生命值 依赖建筑 1 刀斧手 57 06 03 50 2 阔剑手 97 16 03 70 3 投石兵 4 木弓手 32 06 53 35 5 十字弓手 6 战车射手 42 06 73 80 7 黄金黑骑 82 06 2 73 103 8 战象射手 52 06 73 600 9 侦…

有什么软件可以翻译文档?这几款文本翻译软件效果不错

随着世界的全球化&#xff0c;我们越来越需要通过语言进行跨文化交流。但是&#xff0c;不同国家和地区使用的语言却存在差异&#xff0c;这就需要我们掌握一些文本翻译技巧。那么&#xff0c;你是否想过如何实现文本翻译呢&#xff1f;在本文中&#xff0c;我们将给你介绍一些…