QT:日历(QCalendarWidget)

一、简介

       Qt的demo中有CalendarWidget的里,本程序将其国际化,并随时隐藏不必要的设计部件,根据网上的例子增加了一些配置按钮和公历对农历的一些转换,并修复了一些故障。主要目的是掌握其布局的紧凑,并熟悉一些部件的隐藏操作。

二、运行图

(1)程序运行,显示当前的日历,如下图1所示。


三、详解

1、时钟按钮

点击第二个按钮为时钟按钮(第一个按钮为回到今天的日期),其显示如下图2所示。

时钟显示的是当前的时间,具体的设计可以参看本分类中的相应的文章。

2、设置按钮

[cpp]  view plain  copy
  1. void Window::ConfigureButtonClicked()  
  2. {  
  3.     if (m_ConfigureButton->text() == tr("display")) {  
  4.         generalOptionsGroupBox->setHidden(false);  
  5.         datesGroupBox->setHidden(false);  
  6.         textFormatsGroupBox->setHidden(false);  
  7.         m_ConfigureButton->setText(tr("hidden"));  
  8.         m_ConfigureButton->setToolTip(tr("hide setup"));  
  9.   
  10.         previewGroupBox->setTitle(tr("Preview"));  
  11.     }  
  12.     else if (m_ConfigureButton->text() == tr("hidden")) {  
  13.         generalOptionsGroupBox->setHidden(true);  
  14.         datesGroupBox->setHidden(true);  
  15.         textFormatsGroupBox->setHidden(true);  
  16.         m_ConfigureButton->setText(tr("display"));  
  17.         m_ConfigureButton->setToolTip(tr("display setup"));  
  18.   
  19.         previewGroupBox->setTitle(tr("Calendar"));  
  20.     }  
  21. }  

点击第三个按钮为显示设置按钮,再次点击将隐藏部分部件,回到图1,点击后其显示如下图3所示。

QT:日历(QCalendarWidget)_第1张图片

大体的配置跟Qtdemo的例子很相像,增加了设置自己的生日和前往自己的生日按钮,和回到今天。

QT:日历(QCalendarWidget)_第2张图片

[cpp]  view plain  copy
  1. SetBirthday::SetBirthday(QWidget *parent) :  
  2.     QDialog(parent)  
  3. {  
  4.     QLabel* birthdayLabel = new QLabel(tr("birthday:"));  
  5.   
  6.     birthdayDateEdit = new QDateEdit(QDate::currentDate(), this);  
  7.     birthdayDateEdit->setDisplayFormat("yyyy-MM-dd");  
  8.     QHBoxLayout* editLayout = new QHBoxLayout;  
  9.     editLayout->addWidget(birthdayLabel);  
  10.     editLayout->addWidget(birthdayDateEdit);  
  11.   
  12.     QPushButton* okBtn = new QPushButton(tr("ok"));  
  13.     QPushButton* cancelBtn = new QPushButton(tr("cancle"));  
  14.     QHBoxLayout* btnLayout = new QHBoxLayout;  
  15.     btnLayout->setSpacing(20);  
  16.     btnLayout->addWidget(okBtn);  
  17.     btnLayout->addWidget(cancelBtn);  
  18.   
  19.     QVBoxLayout* dlgLayout = new QVBoxLayout;  
  20.     dlgLayout->setMargin(10);  
  21.     dlgLayout->addLayout(editLayout);  
  22.     dlgLayout->addStretch(10);  
  23.     dlgLayout->addLayout(btnLayout);  
  24.     setLayout(dlgLayout);  
  25.   
  26.     connect(okBtn, SIGNAL(clicked()), this, SLOT(accept()));  
  27.     connect(cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));  
  28.   
  29.     setWindowTitle(tr("set_birthday"));  
  30.     resize(200, 100);  
  31. }  

3、关于按钮

[cpp]  view plain  copy
  1. void Window::AboutButtonClicked()  
  2. {  
  3.     QMessageBox::about(this, tr("About Calendar"),  
  4.          tr("

     Calendar 2014

    "
      
  5.   
  6.          "

    Release 1.0

    "
      
  7.          "

    Copyright © 2013-2014 Inc. & isoft "  

  8.          "All rights reserved."  
  9.          "

    版权所有 © 2013-2014 Inc. & isoft。 保留所有权利。"  

  10.          "

    警告:本计算机程序受著作权法和国际公约的保护,未经授权擅自复制或传播本程序"  

  11.          "的部分或全部,可能受到严厉的民事及刑事制裁,并将在法律许可的范围内受到最大"  
  12.          "可能的起诉。"  
  13.             ));  
  14. }  

点击第四个按钮为关于产品的按钮,其内容可以自己设定,只需修改QString的内容,其显示如下图4所示。

QT:日历(QCalendarWidget)_第3张图片

4、公历转农历

       公历转农历的程序在本分类的博文中也有详细的介绍,可以参照,但只能计算1921-2021年间的农历,当超出了这个范围就无法显示农历了,网上也有建议使用sqlite读取了一个农历的数据库,但不知道农历数据库怎么创建起来,所以以后再考虑。显示结果如下图5所示。

QT:日历(QCalendarWidget)_第4张图片

[cpp]  view plain  copy
  1. void Window::selectedDateChanged()  
  2. {  
  3.     QString outLunarMD = "", outLunarYear = "", outLunarMonth = "", outLunarDay = "";  
  4.     currentDateEdit->setDate(calendar->selectedDate());  
  5.     m_detail->setText(calendar->selectedDate().toString("yyyy-MM-dd dddd"));  
  6.     m_day->setText(calendar->selectedDate().toString("dd"));  
  7.   
  8.     if (((calendar->selectedDate().year() > 1921 )  
  9.         || (calendar->selectedDate().year() == 1921 && calendar->selectedDate().month() > 2)  
  10.         || (calendar->selectedDate().year() == 1921 && calendar->selectedDate().month() == 2 && calendar->selectedDate().day() >= 8))  
  11.         && (calendar->selectedDate().year() < 2021))  
  12.     {  
  13.         get_chinese_calendar(calendar->selectedDate(), outLunarMD, outLunarYear, outLunarMonth, outLunarDay);  
  14.         m_mouthday->setVisible(true);  
  15.         m_gregorian->setVisible(true);  
  16.         m_mouthday->setText(outLunarMD);  
  17.         m_gregorian->setText(outLunarYear + " " + outLunarMonth + " " + outLunarDay);  
  18.     }  
  19.     else {  
  20.         m_mouthday->setVisible(false);  
  21.         m_gregorian->setVisible(false);  
  22.     }  
  23. }  

5、保存配置信息

      因本程序配置信息比较多,采用QSettings m_settings("i-soft.com.cn", "calendar");保存上次配置的信息,下次程序启动时用户不用在重新配置。

[cpp]  view plain  copy
  1. void Window::ReadHistorySettings()  
  2. {  
  3.     QSettings m_settings("i-soft.com.cn""calendar");  
  4.     localeCombo->setCurrentIndex(m_settings.value("Language").toInt());  
  5.     firstDayCombo->setCurrentIndex(m_settings.value("WeekStart").toInt());  
  6.     selectionModeCombo->setCurrentIndex(m_settings.value("Selection_Mode").toInt());  
  7.     gridCheckBox->setChecked(m_settings.value("Show_Grid").toBool());  
  8.     navigationCheckBox->setChecked(m_settings.value("Show_Navigation_Bar").toBool());  
  9.     horizontalHeaderCombo->setCurrentIndex(m_settings.value("Horizontal_Header").toInt());  
  10.     verticalHeaderCombo->setCurrentIndex(m_settings.value("Vertival_Header").toInt());  
  11.     weekdayColorCombo->setCurrentIndex(m_settings.value("WeekdayColor").toInt());  
  12.     weekendColorCombo->setCurrentIndex(m_settings.value("WeekendColor").toInt());  
  13.     headerTextFormatCombo->setCurrentIndex(m_settings.value("Header_Font").toInt());  
  14.     firstFridayCheckBox->setChecked(m_settings.value("First_Friday").toBool());  
  15.     mayFirstCheckBox->setChecked(m_settings.value("May_First").toBool());  
  16.     m_clock->restoreGeometry(m_settings.value("Clock_Geometry").toByteArray());  
  17.     m_Birthday = QDate::fromString(m_settings.value("Birthday_Date").toString(), "yyyy-MM-dd");  
  18.     this->restoreGeometry(m_settings.value("Calendar_Geometry").toByteArray());  
  19.   
  20.     if (m_Birthday.isNull())  
  21.         goBirthday->setEnabled(false);  
  22. }  
  23.   
  24. void Window::WriteCurrentSettings()  
  25. {  
  26.     QSettings m_settings("i-soft.com.cn""calendar");  
  27.     m_settings.setValue("Language", localeCombo->currentIndex());  
  28.     m_settings.setValue("WeekStart", firstDayCombo->currentIndex());  
  29.     m_settings.setValue("Selection_Mode", selectionModeCombo->currentIndex());  
  30.     m_settings.setValue("Show_Grid", gridCheckBox->isChecked());  
  31.     m_settings.setValue("Show_Navigation_Bar", navigationCheckBox->isChecked());  
  32.     m_settings.setValue("Horizontal_Header", horizontalHeaderCombo->currentIndex());  
  33.     m_settings.setValue("Vertival_Header", verticalHeaderCombo->currentIndex());  
  34.     m_settings.setValue("WeekdayColor", weekdayColorCombo->currentIndex());  
  35.     m_settings.setValue("WeekendColor", weekendColorCombo->currentIndex());  
  36.     m_settings.setValue("Header_Font", headerTextFormatCombo->currentIndex());  
  37.     m_settings.setValue("First_Friday", firstFridayCheckBox->isChecked());  
  38.     m_settings.setValue("May_First", mayFirstCheckBox->isChecked());  
  39.     m_settings.setValue("Clock_Geometry", m_clock->saveGeometry());  
  40.     m_settings.setValue("Birthday_Date", m_Birthday.toString ("yyyy-MM-dd"));  
  41.     m_settings.setValue("Calendar_Geometry"this->saveGeometry());  
  42. }  
        配置文件会由系统生成(当然也可以自己定义配置文件settings = QSettings("./config.ini", QSettings.IniFormat)),windows下是在注册表里,linux是在当前用户目录下的.config文件中如/home/aoyang/.config/i-soft.com.cn。打开文件的内容如下图6所示。

QT:日历(QCalendarWidget)_第5张图片

6、鼠标右键

[cpp]  view plain  copy
  1. {  
  2.        // TODO:  Context Menu  
  3.         m_ReturnTodayAction = new QAction(tr("Mtoday"), this);  
  4.         m_ReturnTodayAction->setIcon(QIcon(":/images/go_back_today.png"));  
  5.         m_ReturnTodayAction->setShortcut(tr("F9"));  
  6.         m_ShowClockAction = new QAction(tr("Mclock"), this);  
  7.         m_ShowClockAction->setIcon(QIcon(":/images/clock.ico"));  
  8.         m_ShowClockAction->setShortcut(tr("F10"));  
  9.         m_ConfigureButtonAction = new QAction(tr("Msetup"), this);  
  10.         m_ConfigureButtonAction->setIcon(QIcon(":/images/configure.png"));  
  11.         m_ConfigureButtonAction->setShortcut(tr("Ctrl+G"));  
  12.         connect(m_ReturnTodayAction, SIGNAL(triggered()), this, SLOT(ReturnToday()));  
  13.         connect(m_ShowClockAction, SIGNAL(triggered()), SLOT(ShowClockButtonClicked()));  
  14.         connect(m_ConfigureButtonAction, SIGNAL(triggered()), this, SLOT(ConfigureButtonClicked()));  
  15. }  
  16. void Window::CreateContextMenu()  
  17. {  
  18.     previewGroupBox->addAction(m_ReturnTodayAction);  
  19.     previewGroupBox->addAction(m_ShowClockAction);  
  20.     previewGroupBox->addAction(m_ConfigureButtonAction);  
  21.     previewGroupBox->setContextMenuPolicy(Qt::ActionsContextMenu);  
  22. }  
       增加鼠标右键的响应事件,添加previewGroupBox->setContextMenuPolicy(Qt::ActionsContextMenu);也可以重载contextMenuEvent函数在其中增加QMenu和信号槽。如下代码所示(未采用)。
[cpp]  view plain  copy
  1. void Window::contextMenuEvent(QContextMenuEvent*event)  
  2. {  
  3.     QCursorcur=this->cursor();  
  4.     QMenu*menu=newQMenu(this);  
  5.     menu->addAction("delete");  
  6.     menu->exec(cur.pos());  
  7. }  

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文件。

QT:日历(QCalendarWidget)_第6张图片

[cpp]  view plain  copy
  1. {   
  2.     QTranslator translator(0);  
  3.     translator.load("calendar.qm",":/");  
  4.     app.installTranslator(&translator);  
  5. }  

有些未实现国际化,window下若乱码,则在window.cpp构造函数中添加:

[html]  view plain  copy
  1. QTextCodec *codec = QTextCodec::codecForName("utf8");  
  2. QTextCodec::setCodecForLocale(codec);  
  3. QTextCodec::setCodecForCStrings(codec);  
  4. 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。

你可能感兴趣的:(QT)