一、简介
Qt的demo中有CalendarWidget的里,本程序将其国际化,并随时隐藏不必要的设计部件,根据网上的例子增加了一些配置按钮和公历对农历的一些转换,并修复了一些故障。主要目的是掌握其布局的紧凑,并熟悉一些部件的隐藏操作。
二、运行图
(1)程序运行,显示当前的日历,如下图1所示。
三、详解
1、时钟按钮
点击第二个按钮为时钟按钮(第一个按钮为回到今天的日期),其显示如下图2所示。
时钟显示的是当前的时间,具体的设计可以参看本分类中的相应的文章。
2、设置按钮
- void Window::ConfigureButtonClicked()
- {
- if (m_ConfigureButton->text() == tr("display")) {
- generalOptionsGroupBox->setHidden(false);
- datesGroupBox->setHidden(false);
- textFormatsGroupBox->setHidden(false);
- m_ConfigureButton->setText(tr("hidden"));
- m_ConfigureButton->setToolTip(tr("hide setup"));
-
- previewGroupBox->setTitle(tr("Preview"));
- }
- else if (m_ConfigureButton->text() == tr("hidden")) {
- generalOptionsGroupBox->setHidden(true);
- datesGroupBox->setHidden(true);
- textFormatsGroupBox->setHidden(true);
- m_ConfigureButton->setText(tr("display"));
- m_ConfigureButton->setToolTip(tr("display setup"));
-
- previewGroupBox->setTitle(tr("Calendar"));
- }
- }
点击第三个按钮为显示设置按钮,再次点击将隐藏部分部件,回到图1,点击后其显示如下图3所示。
大体的配置跟Qtdemo的例子很相像,增加了设置自己的生日和前往自己的生日按钮,和回到今天。
- SetBirthday::SetBirthday(QWidget *parent) :
- QDialog(parent)
- {
- QLabel* birthdayLabel = new QLabel(tr("birthday:"));
-
- birthdayDateEdit = new QDateEdit(QDate::currentDate(), this);
- birthdayDateEdit->setDisplayFormat("yyyy-MM-dd");
- QHBoxLayout* editLayout = new QHBoxLayout;
- editLayout->addWidget(birthdayLabel);
- editLayout->addWidget(birthdayDateEdit);
-
- QPushButton* okBtn = new QPushButton(tr("ok"));
- QPushButton* cancelBtn = new QPushButton(tr("cancle"));
- QHBoxLayout* btnLayout = new QHBoxLayout;
- btnLayout->setSpacing(20);
- btnLayout->addWidget(okBtn);
- btnLayout->addWidget(cancelBtn);
-
- QVBoxLayout* dlgLayout = new QVBoxLayout;
- dlgLayout->setMargin(10);
- dlgLayout->addLayout(editLayout);
- dlgLayout->addStretch(10);
- dlgLayout->addLayout(btnLayout);
- setLayout(dlgLayout);
-
- connect(okBtn, SIGNAL(clicked()), this, SLOT(accept()));
- connect(cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
-
- setWindowTitle(tr("set_birthday"));
- resize(200, 100);
- }
3、关于按钮
- void Window::AboutButtonClicked()
- {
- QMessageBox::about(this, tr("About Calendar"),
- tr("<h1> Calendar 2014</h1>"
-
- "<p><h4>Release 1.0</h4>"
- "<p>Copyright © 2013-2014 Inc. & isoft "
- "All rights reserved."
- "<p>版权所有 © 2013-2014 Inc. & isoft。 保留所有权利。"
- "<p>警告:本计算机程序受著作权法和国际公约的保护,未经授权擅自复制或传播本程序"
- "的部分或全部,可能受到严厉的民事及刑事制裁,并将在法律许可的范围内受到最大"
- "可能的起诉。"
- ));
- }
点击第四个按钮为关于产品的按钮,其内容可以自己设定,只需修改QString的内容,其显示如下图4所示。
4、公历转农历
公历转农历的程序在本分类的博文中也有详细的介绍,可以参照,但只能计算1921-2021年间的农历,当超出了这个范围就无法显示农历了,网上也有建议使用sqlite读取了一个农历的数据库,但不知道农历数据库怎么创建起来,所以以后再考虑。显示结果如下图5所示。
- void Window::selectedDateChanged()
- {
- QString outLunarMD = "", outLunarYear = "", outLunarMonth = "", outLunarDay = "";
- currentDateEdit->setDate(calendar->selectedDate());
- m_detail->setText(calendar->selectedDate().toString("yyyy-MM-dd dddd"));
- m_day->setText(calendar->selectedDate().toString("dd"));
-
- if (((calendar->selectedDate().year() > 1921 )
- || (calendar->selectedDate().year() == 1921 && calendar->selectedDate().month() > 2)
- || (calendar->selectedDate().year() == 1921 && calendar->selectedDate().month() == 2 && calendar->selectedDate().day() >= 8))
- && (calendar->selectedDate().year() < 2021))
- {
- get_chinese_calendar(calendar->selectedDate(), outLunarMD, outLunarYear, outLunarMonth, outLunarDay);
- m_mouthday->setVisible(true);
- m_gregorian->setVisible(true);
- m_mouthday->setText(outLunarMD);
- m_gregorian->setText(outLunarYear + " " + outLunarMonth + " " + outLunarDay);
- }
- else {
- m_mouthday->setVisible(false);
- m_gregorian->setVisible(false);
- }
- }
5、保存配置信息
因本程序配置信息比较多,采用QSettings m_settings("i-soft.com.cn", "calendar");保存上次配置的信息,下次程序启动时用户不用在重新配置。
- void Window::ReadHistorySettings()
- {
- QSettings m_settings("i-soft.com.cn", "calendar");
- localeCombo->setCurrentIndex(m_settings.value("Language").toInt());
- firstDayCombo->setCurrentIndex(m_settings.value("WeekStart").toInt());
- selectionModeCombo->setCurrentIndex(m_settings.value("Selection_Mode").toInt());
- gridCheckBox->setChecked(m_settings.value("Show_Grid").toBool());
- navigationCheckBox->setChecked(m_settings.value("Show_Navigation_Bar").toBool());
- horizontalHeaderCombo->setCurrentIndex(m_settings.value("Horizontal_Header").toInt());
- verticalHeaderCombo->setCurrentIndex(m_settings.value("Vertival_Header").toInt());
- weekdayColorCombo->setCurrentIndex(m_settings.value("WeekdayColor").toInt());
- weekendColorCombo->setCurrentIndex(m_settings.value("WeekendColor").toInt());
- headerTextFormatCombo->setCurrentIndex(m_settings.value("Header_Font").toInt());
- firstFridayCheckBox->setChecked(m_settings.value("First_Friday").toBool());
- mayFirstCheckBox->setChecked(m_settings.value("May_First").toBool());
- m_clock->restoreGeometry(m_settings.value("Clock_Geometry").toByteArray());
- m_Birthday = QDate::fromString(m_settings.value("Birthday_Date").toString(), "yyyy-MM-dd");
- this->restoreGeometry(m_settings.value("Calendar_Geometry").toByteArray());
-
- if (m_Birthday.isNull())
- goBirthday->setEnabled(false);
- }
-
- void Window::WriteCurrentSettings()
- {
- QSettings m_settings("i-soft.com.cn", "calendar");
- m_settings.setValue("Language", localeCombo->currentIndex());
- m_settings.setValue("WeekStart", firstDayCombo->currentIndex());
- m_settings.setValue("Selection_Mode", selectionModeCombo->currentIndex());
- m_settings.setValue("Show_Grid", gridCheckBox->isChecked());
- m_settings.setValue("Show_Navigation_Bar", navigationCheckBox->isChecked());
- m_settings.setValue("Horizontal_Header", horizontalHeaderCombo->currentIndex());
- m_settings.setValue("Vertival_Header", verticalHeaderCombo->currentIndex());
- m_settings.setValue("WeekdayColor", weekdayColorCombo->currentIndex());
- m_settings.setValue("WeekendColor", weekendColorCombo->currentIndex());
- m_settings.setValue("Header_Font", headerTextFormatCombo->currentIndex());
- m_settings.setValue("First_Friday", firstFridayCheckBox->isChecked());
- m_settings.setValue("May_First", mayFirstCheckBox->isChecked());
- m_settings.setValue("Clock_Geometry", m_clock->saveGeometry());
- m_settings.setValue("Birthday_Date", m_Birthday.toString ("yyyy-MM-dd"));
- m_settings.setValue("Calendar_Geometry", this->saveGeometry());
- }
配置文件会由系统生成(当然也可以自己定义配置文件settings = QSettings("./config.ini", QSettings.IniFormat)),windows下是在注册表里,linux是在当前用户目录下的.config文件中如/home/aoyang/.config/i-soft.com.cn。打开文件的内容如下图6所示。
6、鼠标右键
- {
-
- m_ReturnTodayAction = new QAction(tr("Mtoday"), this);
- m_ReturnTodayAction->setIcon(QIcon(":/images/go_back_today.png"));
- m_ReturnTodayAction->setShortcut(tr("F9"));
- m_ShowClockAction = new QAction(tr("Mclock"), this);
- m_ShowClockAction->setIcon(QIcon(":/images/clock.ico"));
- m_ShowClockAction->setShortcut(tr("F10"));
- m_ConfigureButtonAction = new QAction(tr("Msetup"), this);
- m_ConfigureButtonAction->setIcon(QIcon(":/images/configure.png"));
- m_ConfigureButtonAction->setShortcut(tr("Ctrl+G"));
- connect(m_ReturnTodayAction, SIGNAL(triggered()), this, SLOT(ReturnToday()));
- connect(m_ShowClockAction, SIGNAL(triggered()), SLOT(ShowClockButtonClicked()));
- connect(m_ConfigureButtonAction, SIGNAL(triggered()), this, SLOT(ConfigureButtonClicked()));
- }
- void Window::CreateContextMenu()
- {
- previewGroupBox->addAction(m_ReturnTodayAction);
- previewGroupBox->addAction(m_ShowClockAction);
- previewGroupBox->addAction(m_ConfigureButtonAction);
- previewGroupBox->setContextMenuPolicy(Qt::ActionsContextMenu);
- }
增加鼠标右键的响应事件,添加previewGroupBox->setContextMenuPolicy(Qt::ActionsContextMenu);也可以重载contextMenuEvent函数在其中增加QMenu和信号槽。如下代码所示(未采用)。
- void Window::contextMenuEvent(QContextMenuEvent*event)
- {
- QCursorcur=this->cursor();
- QMenu*menu=newQMenu(this);
- menu->addAction("delete");
- menu->exec(cur.pos());
- }
7、国际化支持
国际化过程:
(1)使用tr()将需要翻译的字符串标记出来,lupdate工具只提取出tr()函数中的相关字符串。
(2)在pro文件中增加一行:TRANSLATIONS += myapp.ts。
(3)pro文件所在的文件夹,然后输入命令lupdate MyApp.pro。
(4)Qt Linguist打开我们的ts文件,然后进行翻译。
(5)lrelease MyApp.pro发布生成myapp.qm文件。
(6)加载myapp.qm文件。
- {
- QTranslator translator(0);
- translator.load("calendar.qm",":/");
- app.installTranslator(&translator);
- }
有些未实现国际化,window下若乱码,则在window.cpp构造函数中添加:
- QTextCodec *codec = QTextCodec::codecForName("utf8");
- QTextCodec::setCodecForLocale(codec);
- QTextCodec::setCodecForCStrings(codec);
- QTextCodec::setCodecForTr(codec);
四、总结
(1)Qt中的CalendarWidget在Widgets下,相应的说明可以参看其英文文档,其他的部分可以下载源码详细分析。
(2)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/7527775)。
(3)所用的Qt的库Qt4.6.2,GCC4.4.6 20120305 (Red Hat 4.4.6-4) 。系统是centos6.3。