SSD4 实验四 《日期/时间控制面板》

 

目录

1.需求分析

2.概要设计

1.首先确定开发工具:

2.数据结构定义:

3.具体功能的概要设计:

3.详细设计(分模块介绍)

1.分页显示的功能:

2.日历的功能:

3.24小时制和12小时制的转换:

4.日期时间的改变:

 5.时区的改变导致日期和时间的改变:

  6.时钟的绘画:

4.调试分析

1.如何向导入comboBox导入时区信息:

2.地图上的箭头:

3.画时钟时,困扰在了如何只在tab中显示时钟,这个问题上:

5.用户使用说明

6.测试结果(只展示部分)

1.打开程序,显示系统当前的日期和时间

 2.改变为12小时制,观察到时间的变化

 3.改变时区为utc-12:00,查看地图箭头,时间,日期,时钟的变化。

 4.点击OK:

7.附录

mainwindow.h: 

mainwindow.cpp:

main.cpp:


1.需求分析

创建一个实现完整的日期/时间控制面板的接口(仿照标准的 Windows 98 控制面板)。如下所 示,该界面应该包含一个带有两个窗格的选项卡对话框控件:一个用于设置日期和时间,另一个用于设置。 时区。“日期和时间”选项卡将是这个任务的新选项卡,应该像这里所示的那样。对于“时区”选项卡,您应该使用在之前的编程任务中创建的接口组件和代码。

 

 你构建的界面应该包括一个选项卡对话框容器,以及“OK”、“取消”和“应用”按钮。选项卡对话框容器应该有两个选项卡-为这个分配构造的“日期和时间”选项卡和从以前的分配中获得的”时区”选项卡。“日期和时间”选项卡应该包含两个帧(一个用于日期,一个用于时间)和一个显示当前选择的时区 (但不显示时区与 GMT 的偏移)的标签。“日期”框架应该允许用户指定月、年和日。这应该使用用于月份和文本框的组合框控件和用于年份的上下控件,以及用于显示和更改日期的日历控件来完成。“日期和时间”选项卡的“时间”框架应该包括一组用于小时、分钟、秒和上午/下午设置的控件。每一个小时、分钟和第二个界面都应该由一个文本框和一个数字倒置控件组成。am/pm 界面应该由两个单选按钮组成的组(控制数组)。 界面的最后一部分应该由“OK”、“取消”和“应用”按钮组成。当用户按下“OK”或“取消”按钮时,您应该生成一个当前设置的小报告(类似于下面所示的),然后退出界面(通过”卸载”表单)。如果用户按下了“Apply”按钮,你应该会生成一个类似的报告,但不会退出界面。与前面的练习一样,可以使用提供的子例程创建报告。

 

 

2.概要设计

1.首先确定开发工具:

还是依照习惯,采用了Qt 5.12.1开发,语言是C++。

2.数据结构定义:

实验使用了Qt自带的组件,组件如下:

值得注意的是,本程序使用了几个较难理解的变量:

UTC代表的是当前的国际协调时间,是变化的。utcData[]这个数组存储的是comboBox的时区时间距离UTC的时间大小,即该时区时间+utcData[]=UTC。pri存储的是上一个时区在comboBox中的位置。

3.具体功能的概要设计:

  1. 进入程序,可以修改左侧日历日期,也可以修改右侧时间。改变小时制的复选框,可以使时间以24小时制或者12小时制带am,pm的方式呈现。
  2. 时间的更改方式同实验三一样。
  3. 时间更改之后时钟也会更改,如果退回到前一天或者前进到后一天的时间,那么日期也会更改。
  4. 更改时区,再点击应用之后,会弹出提示框,并且时间和日期(如果更改后的时区不是同一天)也会更改。
  5. 点击OK和Cancel,会弹出提示框,并关闭页面。

 

 

3.详细设计(分模块介绍)

1.分页显示的功能:

 

通过tabWidget组件实现。

2.日历的功能:

通过calendarWidget组件实现 。

3.24小时制和12小时制的转换:

   24小时制的功能可以直接参考实验三。至于12小时的转换,其实底层都是用24小时来存储的,只是显示的时候改变了而已,例如当前是13点,用12小时制表示,那么存储的是13,显示出来13-1 pm。因此需要引入两个bool变量来判断当前是am还是pm,如果都不是,那么两个都是false.

例如:

4.日期时间的改变:

   因为时间的改变也会导致日期的改变,所以需要用代码去改变日期,这里写了两个函数,用来改变日期,主要用到的是setselectedDate()这个函数。

   例如:

 5.时区的改变导致日期和时间的改变:

  这个功能是在点击应用之后起作用的,更改时区,在点击应用之后,如果时间和日期发生变化那么相应的日历会改变,时间控件和时钟都会改变。

   具体实现原理是:

   先根据pri得到上一个时区在comboBox中的下标,然后找到该下标在utcData中相对应的值,这个值加上当前的hour就是UTC。在得到了UTC之后,又可以根据现在的comboBox的值的下标和在utcData对应的值得到目前时区的时间。

   例如:

  6.时钟的绘画:

   写了一个绘画函数,用来显示时钟.

   写了一个事件过滤器,实现只在tab中显示这个时钟。

 

 

4.调试分析

1.如何向导入comboBox导入时区信息:

   本来打算直接手敲的(貌似windows中的时区不能直接复制进去),后来找到了一个命令,可以在命令行中显示当前系统中包含的时区,然后再将数据复制进去。

   在命令提示符下使用:win+R输入cmd回车进入cmd然后输入这行代码即可:tzutil /l

2.地图上的箭头:

实际上用的是一个QLabel,在label上插入了一张箭头的图片,当时区改变时,改变其坐标即可。

3.画时钟时,困扰在了如何只在tab中显示时钟,这个问题上:

如果仅仅是QPainter pan(ui->tab);QPainter painter(ui->tab);

那么会显示不出来时钟,所以采用了一个事件过滤器。

5.用户使用说明

1.进入程序,可以修改左侧日历日期,也可以修改右侧时间。改变小时制的复选框,可以使时间以24小时制或者12小时制带am,pm的方式呈现。

2.时间的更改方式同实验三一样。

3.时间更改之后时钟也会更改,如果退回到前一天或者前进到后一天的时间,那么日期也会更改。

4.更改时区,再点击应用之后,会弹出提示框,并且时间和日期(如果更改后的时区不是同一天)也会更改。

5.点击OK和Cancel,会弹出提示框,并关闭页面。

6.测试结果(只展示部分)

1.打开程序,显示系统当前的日期和时间

 2.改变为12小时制,观察到时间的变化

 3.改变时区为utc-12:00,查看地图箭头,时间,日期,时钟的变化。

 

 

 4.点击OK:

 

7.附录

mainwindow.h: 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include 
#includenamespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();void dateAdd();void dateDec();bool eventFilter(QObject *watched, QEvent *event);private slots:void on_comboBox_currentIndexChanged(const QString &arg1);void on_hourClockcomboBox_currentIndexChanged(int index);void on_radioButton_toggled(bool checked);void on_radioButton_2_toggled(bool checked);void on_spinBox_valueChanged(const QString &arg1);void on_spinBox_2_valueChanged(const QString &arg1);void on_spinBox_3_valueChanged(const QString &arg1);void on_pushButton_3_clicked();void on_pushButton_clicked();void on_pushButton_2_clicked();void paintEven();private:Ui::MainWindow *ui;int hour=0,min=0,second=0;bool am=false,pm=false;int UTC=0;int utcData[45]={12,11,10,10,9,9,8,8,8,7,7,7,7,6,6,6,6,6,5,5,5,0,-5,-6,-7,-8,-8,-8,-8,-9,-9,-9,-10,-11,-11,-12,-12,-13,-13,-14};int pri=25;//QTimer *tim;
};#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"windows.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{/******写一下需求:**/ui->setupUi(this);setWindowTitle(tr("Date/Time"));menuBar()->setVisible(false);//隐藏菜单栏ui->mainToolBar->setVisible(false);//隐藏工具栏ui->tabWidget->setTabPosition(QTabWidget::North);//设置选项卡的方位东南西北,默认在上方ui->tabWidget->setMovable(true);//label设置图片QPixmap *pixmap = new QPixmap("images/timezone_map_small.gif");pixmap->scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);ui->label->setScaledContents(true);ui->label->setPixmap(*pixmap);//arrowLabel设置图片pixmap = new QPixmap("images/向下箭头粗小.png");pixmap->scaled(ui->arrowLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);ui->arrowLabel->setScaledContents(true);ui->arrowLabel->setPixmap(*pixmap);//获取当前时间,并设置成初始值QTime time;hour=time.currentTime().hour();UTC=hour-8;min=time.currentTime().minute();second=time.currentTime().second();ui->spinBox->setValue(hour);ui->spinBox_2->setValue(min);ui->spinBox_3->setValue(second);//标签默认显示ui->label_2->setText(tr("Current Time Zone: (UTC+08:00) 北京,重庆,香港特别行政区,乌鲁木齐"));//combobox默认显示ui->comboBox->setCurrentIndex(25);//combobox2默认显示,radioButton不能点击ui->hourClockcomboBox->setCurrentIndex(1);ui->radioButton->setEnabled(false);ui->radioButton_2->setEnabled(false);//spinbox默认设置ui->spinBox->setMinimum(-1);ui->spinBox->setMaximum(24);ui->spinBox_2->setMinimum(-1);ui->spinBox_2->setMaximum(60);ui->spinBox_3->setMinimum(-1);ui->spinBox_3->setMaximum(60);ui->tab->installEventFilter(this);//tim=new QTimer(this);//connect(tim,SIGNAL(timeout()), this,SLOT(paintEven()));//tim->start(1);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::dateAdd()
{//日期也要更改了int year=ui->calendarWidget->yearShown();int month=ui->calendarWidget->monthShown();QDate old_d=ui->calendarWidget->selectedDate();int day=old_d.day();day++;if (month==1||month==3||month==5||month==7||month==8||month==10||month==12){if (day>31){month++;day=1;if (month>12){year++;month=1;}}}else if (month!=2){if (day>30){month++;day=1;}}else{if(bool run=QDate::isLeapYear(year)){if (day>29){month++;day=1;}}else{if (day>28){month++;day=1;}}}QDate new_d(year,month,day);ui->calendarWidget->setSelectedDate(new_d);qDebug()<calendarWidget->selectedDate();
}void MainWindow::dateDec()
{//日期也要更改了int year=ui->calendarWidget->yearShown();int month=ui->calendarWidget->monthShown();QDate old_d=ui->calendarWidget->selectedDate();int day=old_d.day();day--;if (month==2||month==4||month==6||month==8||month==9||month==11||month==1){if (day<1){month--;day=31;if (month<1){year--;month=12;}}}else if (month!=3){if (day<1){month--;day=30;}}else{if(bool run=QDate::isLeapYear(year)){if (day<1){month--;day=29;}}else{if (day<1){month--;day=28;}}}QDate new_d(year,month,day);ui->calendarWidget->setSelectedDate(new_d);qDebug()<calendarWidget->selectedDate();
}void MainWindow::paintEven()
{QPainter pan(ui->tab);QPixmap map(":/timg2.jpg");//将背景图取出QRect q(0,0,1920,1200);// (0,0)为左上点,(1024,1024)为右下点,以此矩形取出上诉图片QRect q2(0,0,1024,1024);//定义背景图大小//pan.drawPixmap(q2,map,q);//得到背景图QPainter painter(ui->tab);//声明一个画家对象painter.translate(690,170);//平移坐标系,后续时针的中点就在平移后坐标系的原点//相当于画家作画本来是默认从(0,0)开始,现在你命令他移动到你给的位置去,以你给的位置开始作画painter.scale(1.5,1.5);//按比例额缩放坐标系,此处为放大两倍,将横纵坐标都放大两倍,则之后你的时钟也被放大//painter.shear(0,1);painter.save();//保存此时的坐标系状态//开始绘制时针,分针,秒针的颜色。QColor hourC(212,181,227);//分别设置时针,分针,秒针颜色QColor minC(10,100,100);//前三项为三基色三个方向比例度,形成一种颜色,最后一个是不透明度QColor secC(226,207,182);//绘制分针刻度线,一共有60条刻度线,所以要绘制60次for (int i=1;i<=60;i++){//绘制5个像素点长度的刻度线painter.drawLine(0,-80,0,-75); //这个时候可以看上面的世界坐标转换。圆心坐标200,230,为坐标系原点,//他的上方,和左边为负数,右边,和下面为整数painter.rotate(6); //一分钟旋转6度。其实就是以此时的原点为中心将绘画区域旋转6度}// painter.setPen(hour);//绘制时针刻度线,同上for (int i=1;i<=60;i++){if(i%5==0)//每隔五格可一次{//绘制5个像素点长度的刻度线// painter.setPen(Qt::red|Qt::cyan);painter.drawLine(0,-80,0,-70);//与上相同painter.rotate(30);//painter.setPen(Qt::red|Qt::blue);//tr("%1").arg(i/5)这个函数,是将数字转换成个字符串,默认情况,是以10进制转换painter.drawText(-3,-60, tr("%1").arg(i/5));//在-3,-60,的位置添加每个刻度代表的数字,即添加钟表刻度数字}}painter.restore();//恢复之前状态//绘制时针,分针,秒针的形状。四个坐标,那就是四边形。注意坐标一定要按顺序写,不然是一个不规则的形状。QPoint  handhour[4]={QPoint(0,-40),QPoint(3,0),QPoint(0,6),QPoint(-3,0),};QPoint  handsec[4]={QPoint(0,-60),QPoint(3,0),QPoint(0,6),QPoint(-3,0),};QPoint  handmin[4]={QPoint(0,-50),QPoint(3,0),QPoint(0,6),QPoint(-3,0),};//显示时针的位置painter.setPen(Qt::NoPen);painter.setBrush(hourC);//填充时针,hour是上述定义过的颜色painter.save();//保存painter.rotate(30.0*(hour+min/60));//time.hour()+time.minute()/60就是说现在是几个小时,乘以三十得到需要转动的//角度painter.drawConvexPolygon(handhour,4); //绘制多边形函数。painter.restore();//切记旋转之后,一定要复位,不然,分针的旋转会在时针的基础上旋转。//显示分针的位置//painter.setPen(Qt::NoPen);painter.setBrush(minC);painter.save();painter.rotate(6.0*(min+second/60));//分针的旋转,以秒针为基础进行painter.drawConvexPolygon(handmin,4);painter.restore();//显示秒针位置painter.setPen(Qt::NoPen);painter.setBrush(secC);painter.save();painter.rotate(second*6);painter.drawConvexPolygon(handsec,4);painter.restore();
}bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{if(watched ==ui->tab&&event->type()==QEvent::Paint){paintEven();}return QWidget::eventFilter(watched,event);
}void MainWindow::on_comboBox_currentIndexChanged(const QString &arg1)
{ui->label_2->setText("Current Time Zone: "+arg1);if (utcData[ui->comboBox->currentIndex()]>0){//说明是西半球的,735是西一区相对应的x的坐标ui->arrowLabel->move(735-24*(utcData[ui->comboBox->currentIndex()]-1),70);}else if (utcData[ui->comboBox->currentIndex()]<=0) {//说明是东半球的,140是协调时所对应的x的坐标,注意这里是负号ui->arrowLabel->move(140-24*(utcData[ui->comboBox->currentIndex()]),70);}qDebug()<arrowLabel->x();
}void MainWindow::on_hourClockcomboBox_currentIndexChanged(int index)
{if(index==0){ui->radioButton->setEnabled(true);ui->radioButton_2->setEnabled(true);if (hour>=12){//hour=hour-12;内部存储应该还是得按照24小时制pm=true;ui->spinBox->setValue(hour-12);ui->spinBox->setMaximum(12);ui->radioButton_2->setChecked(true);}else{am=true;ui->spinBox->setMaximum(12);ui->radioButton->setChecked(true);}}else{am=false;pm=false;ui->radioButton->setEnabled(false);ui->radioButton_2->setEnabled(false);ui->spinBox->setMaximum(24);qDebug()<<"进入这里了,而且hour是:"<spinBox->setValue(hour);}
}void MainWindow::on_radioButton_toggled(bool checked)
{//状态的改变amif (checked&&!am){am=true;pm=false;qDebug()<<"am is:"<spinBox->setValue(arg1.toInt());if (pm){hour=hour+12;qDebug()<<"pm hour is:"<spinBox->setValue(0);hour=0;am=true;pm=false;ui->radioButton->setChecked(true);//日期也要更改了dateAdd();}else if (arg1.compare("-1")==0){ui->spinBox->setValue(11);hour=11;am=true;pm=false;ui->radioButton->setChecked(true);}}else if (am) {if (arg1.compare("12")==0){ui->spinBox->setValue(0);hour=12;//留意pm=true;am=false;ui->radioButton_2->setChecked(true);}else if (arg1.compare("-1")==0){ui->spinBox->setValue(11);hour=11;pm=true;am=false;ui->radioButton_2->setChecked(true);//日期也要更改了dateDec();}}else{if (arg1.compare("24")==0){ui->spinBox->setValue(0);hour=0;//日期也要更改了dateAdd();}else if (arg1.compare("-1")==0){ui->spinBox->setValue(23);hour=23;//日期也要更改了dateDec();}}qDebug()<<"出去时的hour is:"<spinBox_2->setValue(arg1.toInt());if (arg1.compare("60")==0){ui->spinBox_2->setValue(0);min=0;qDebug()<<"2"<spinBox->setValue(hour+1-12);}else{ui->spinBox->setValue(hour+1);//这个地方太牛逼了!!!记录在实验报告里,主要就是重复发射信号的问题}}else if (arg1.compare("-1")==0){ui->spinBox_2->setValue(59);min=59;if (pm){ui->spinBox->setValue(hour-1-12);}else{ui->spinBox->setValue(hour-1);//这个地方太牛逼了!!!记录在实验报告里,主要就是重复发射信号的问题}}
}void MainWindow::on_spinBox_3_valueChanged(const QString &arg1)
{//秒second=arg1.toInt();if (arg1.compare("60")==0){ui->spinBox_3->setValue(0);second=0;qDebug()<<"1"<spinBox_2->setValue(min+1);}else if (arg1.compare("-1")==0){ui->spinBox_3->setValue(59);second=59;ui->spinBox_2->setValue(min-1);}
}void MainWindow::on_pushButton_3_clicked()
{//UTC改变//想到了用QVector去存储,现在太累了,明日再写//不用QVector,用一个变量去存就好了UTC=hour+utcData[pri];//UTC=hour+utcData[ui->comboBox->currentIndex()];
//    if (utcData[ui->comboBox->currentIndex()]==12){
//        for(int i=0;i<20;i++){
//            ui->spinBox->setValue(hour-1);
//        }
//    }if (utcData[pri]<0){for(int i=0;i>utcData[pri];i--){ui->spinBox->setValue(--hour);}}else{for(int i=0;ispinBox->setValue(++hour);}}//将hour改成utc的时间if (utcData[ui->comboBox->currentIndex()]<0){for (int i=0;i>utcData[ui->comboBox->currentIndex()];i--) {ui->spinBox->setValue(++hour);}}else{for (int i=0;icomboBox->currentIndex()];i++) {ui->spinBox->setValue(--hour);}}pri=ui->comboBox->currentIndex();if (ui->checkBox->isChecked()){int year=ui->calendarWidget->yearShown();int month=ui->calendarWidget->monthShown();QDate old_d=ui->calendarWidget->selectedDate();int day=old_d.day();QMessageBox* msg = new QMessageBox(this);msg->setWindowTitle("Date_and_time");msg->setText("Ok...\n==========""\nYear = "+QString::number(year)+"\nMonth = "+QString::number(month)+"\nDay = "+QString::number(day)+"\nHour = "+QString::number(hour)+"\nMinute = "+QString::number(min)+"\nSecond = "+QString::number(second)+"\nTimezone = "+QString(ui->label_2->text())+"\nAuto Daylight = true"+"\n==========");msg->show();msg->exec();}else{int year=ui->calendarWidget->yearShown();int month=ui->calendarWidget->monthShown();QDate old_d=ui->calendarWidget->selectedDate();int day=old_d.day();QMessageBox* msg = new QMessageBox(this);msg->setWindowTitle("Date_and_time");msg->setText("Ok...\n==========""\nYear = "+QString::number(year)+"\nMonth = "+QString::number(month)+"\nDay = "+QString::number(day)+"\nHour = "+QString::number(hour)+"\nMinute = "+QString::number(min)+"\nSecond = "+QString::number(second)+"\nTimezone = "+QString(ui->label_2->text())+"\nAuto Daylight = false"+"\n==========");msg->show();msg->exec();}
}void MainWindow::on_pushButton_clicked()
{if (ui->checkBox->isChecked()){int year=ui->calendarWidget->yearShown();int month=ui->calendarWidget->monthShown();QDate old_d=ui->calendarWidget->selectedDate();int day=old_d.day();QMessageBox* msg = new QMessageBox(this);msg->setWindowTitle("Date_and_time");msg->setText("Ok...\n==========""\nYear = "+QString::number(year)+"\nMonth = "+QString::number(month)+"\nDay = "+QString::number(day)+"\nHour = "+QString::number(hour)+"\nMinute = "+QString::number(min)+"\nSecond = "+QString::number(second)+"\nTimezone = "+QString(ui->label_2->text())+"\nAuto Daylight = true"+"\n=========="+"\n(Time has saved)");msg->show();msg->exec();this->close();}else{int year=ui->calendarWidget->yearShown();int month=ui->calendarWidget->monthShown();QDate old_d=ui->calendarWidget->selectedDate();int day=old_d.day();QMessageBox* msg = new QMessageBox(this);msg->setWindowTitle("Date_and_time");msg->setText("Ok...\n==========""\nYear = "+QString::number(year)+"\nMonth = "+QString::number(month)+"\nDay = "+QString::number(day)+"\nHour = "+QString::number(hour)+"\nMinute = "+QString::number(min)+"\nSecond = "+QString::number(second)+"\nTimezone = "+QString(ui->label_2->text())+"\nAuto Daylight = false"+"\n=========="+"\n(Time has saved)");msg->show();msg->exec();this->close();}}void MainWindow::on_pushButton_2_clicked()
{int year=ui->calendarWidget->yearShown();int month=ui->calendarWidget->monthShown();QDate old_d=ui->calendarWidget->selectedDate();int day=old_d.day();QMessageBox* msg = new QMessageBox(this);msg->setWindowTitle("Date_and_time");msg->setText("Cancelled...\n==========""\nYear = "+QString::number(year)+"\nMonth = "+QString::number(month)+"\nDay = "+QString::number(day)+"\nHour = "+QString::number(hour)+"\nMinute = "+QString::number(min)+"\nSecond = "+QString::number(second)+"\nTimezone = "+"Current Time Zone: (UTC+08:00) 北京,重庆,香港特别行政区,乌鲁木齐"+"\nAuto Daylight = false"+"\n=========="+"\n(Time has saved)");msg->show();msg->exec();this->close();
}

main.cpp:

#include "mainwindow.h"
#include int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

内容仅供参考!!!


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部