写在前面
笔者是大一下计科生,标题这个项目是笔者这个学期的课设,与学长共创,我负责客户端部分,现在已经实现了待办板块的新建、修改。
这个项目目前已经走上正轨了,博主也实现了主要功能的从无到有,现在做打卡板块类似的功能也会很容易,所以这篇博客记录打卡板块功能的初步实现
功能分析
本次主要实现修改控件、打卡块的新建和修改、总时长的计算、是否达标的确认
至于调用系统时钟这个功能后续再做,还有打卡天数自增因为要结合当前时间也是后续再做
思路梳理
这个思路参照待办板块的话是很好实现的,若今日是否达标选了是,则天数+1,选了否,天数清零
打卡块还是用tableView这个控件,用QList型成员变量当中介
计算总时长就是把表中每一个时间段转换为int型,再计算总时长
项目没有什么难点,开始做
具体实现
(1)修改控件
把记录天数的地方改成LineEdit,日期改成LineEdit,任务块改成tableView,修改挪到下边,今日总时长改成LineEdit,今日是否达标设置两个选项,默认为否
记得修改控件的名字
(2)设置成员变量
目前需要一个记录总天数的成员变量、记录总时长的成员变量、建立表格用的模型、模式选择器、选中行索引、中介变量
这段代码写在h文件里:
int allDays;
int allHours;
int allMinutes;
QStandardItemModel *model = new QStandardItemModel(this);
int addOrRevise;
int currentRow;
QTime shiftEndTime;
QTime shiftstartTime;
QString shiftEvent;
(3)初始化表格
仿照待办板块做就行了
//这个函数的作用是获取并初始化TableView控件
void Clock::GetclockShowTableView()
{
//获取界面中的表格对象
QTableView *clockShow = ui->clockShowTableView;
//设置clockShowTableView的表头
model->setColumnCount(3);
model->setHorizontalHeaderLabels({"开始时间","结束时间","事项"});
//设置表格的点击模式
ui->clockShowTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->clockShowTableView->setSelectionMode(QAbstractItemView::SingleSelection);
clockShow->setModel(model);
}
这个函数在clock的构造函数里调用
(4)实现新建修改
这部分还是仿照待办直接做就行
这里有一个需要注意的地方:待办板块的始末时间咋样都无所谓,反正用户能看懂就行,但是打卡板块是要计算一天的总时长的,所以打卡这里要改成时间输入框或按标准格式输入
使用timeEdit控件,然后对应获取代码也要改一下,中介变量也不能是动态数组型的了,而是两个QTime型的和一个QString型的
附一下各个部分的代码:
//这个函数的作用是新建一个打卡的事件
void Clock::on_newClockButton_clicked()
{
ui->stackedWidget->setCurrentIndex(1);
addOrRevise=1;
}
//这个函数的作用是修改已经存在的打卡事件
void Clock::on_reviseButton_clicked()
{
//这段代码的作用是将表格中被选中的行的内容依次存进中介数组
if (currentRow != -1)
{
QModelIndex index = model->index(currentRow, 0);
QVariant data = model->data(index);
shiftStartTime=(data.toTime());
index = model->index(currentRow, 1);
data = model->data(index);
shiftEndTime=(data.toTime());
index = model->index(currentRow, 2);
data = model->data(index);
shiftEvent=(data.toString());
}
//这段代码的作用是在界面中设置中介数组中的内容
ui->startTimeInput->setTime(shiftStartTime);
ui->endTimeInput->setTime(shiftEndTime);
ui->eventInput->setText(shiftEvent);
//要把中介变量清空,方便下次使用
shiftStartTime=QTime(0,0);
shiftEndTime=QTime(0,0);
shiftEvent="";
ui->stackedWidget->setCurrentIndex(1);
}
//这个函数的作用是保存修改或新建的打卡事件------------------------未完成
void Clock::on_clock_applyButton_clicked()
{
ui->stackedWidget->setCurrentIndex(0);
if(addOrRevise==1)
{
//这几行代码的作用是获取第二个界面输入框里的文本
QTime startTime=ui->startTimeInput->time();
QTime endTime=ui->endTimeInput->time();
QString event=ui->eventInput->text();
//这几行代码的作用是向tableView里添加一行
int row = model->rowCount();
model->insertRow(row);
QStandardItem *item = new QStandardItem(startTime.toString());
model->setItem(row, 0, item);
item = new QStandardItem(endTime.toString());
model->setItem(row, 1, item);
item = new QStandardItem(event);
model->setItem(row, 2, item);
//这句代码的作用是清空第二个界面的内容,方便下次使用
QTime orignalTime = QTime(0,0);
ui->startTimeInput->setTime(orignalTime);
ui->endTimeInput->setTime(orignalTime);
ui->eventInput->setText("");
addOrRevise=0;
}
else if(addOrRevise==2)
{
//这段代码的作用是获取当前界面的输入框的内容
QTime startTime=ui->startTimeInput->time();
QTime endTime=ui->endTimeInput->time();
QString event=ui->eventInput->text();
//这个循环的作用是把中介变量的内容传进选中的行中
QStandardItem *item = new QStandardItem(startTime.toString());
model->setItem(currentRow, 0, item);
item = new QStandardItem(endTime.toString());
model->setItem(currentRow, 1, item);
item = new QStandardItem(event);
model->setItem(currentRow, 2, item);
//将界面置空方便下次使用
QTime orignalTime=QTime(0,0);
ui->startTimeInput->setTime(orignalTime);
ui->endTimeInput->setTime(orignalTime);
ui->eventInput->setText("");
//将选择模式置空,防止干扰下次使用
addOrRevise=0;
}
}
//这个函数的作用是标记被选中的行并把模式改成修改
void Clock::on_clockShowTableView_clicked(const QModelIndex &index)
{
currentRow = index.row();
addOrRevise = 2;
}
(5)当天总时长计算
因为我们的时间输入框是QTime型的,所以可以直接提取出小时和分钟数,这个比较容易实现
关键在于要在点击了新建一个东西或修改一个东西应用按钮之后的数据更新
所以这个功能的实现逻辑应该放在应用按钮的槽函数那里
//以下代码的功能是实现当天总时长的更新--------------------------------------------------当天时间过了十二点自动清空功能未实现
int startHour=startTime.hour();
int endMinute=endTime.minute();
int startMinute=startTime.minute();
int endHour=endTime.hour();
if(endMinute>=startMinute)
{
allHours+=endHour-startHour;
allMinutes+=endMinute-startMinute;
if(allMinutes>=60)
{
allMinutes-=60;
allHours++;
}
}
else
{
allHours+=endHour-startHour-1;
allMinutes+=endMinute+60-startMinute;
if(allMinutes>=60)
{
allMinutes-=60;
allHours++;
}
}
QString hour=QString::number(allHours);
QString minute=QString::number(allMinutes);
ui->hourShowEdit->setText(hour);
ui->minuteShowEdit->setText(minute);
这是新建的计数功能
解释一下:按下了应用按钮之后,开始计算这段时间的时长,然后把它们转成字符串型放到输出框
//这段代码的作用是减去被修改的时间段
int startHour=shiftStartTime.hour();
int endMinute=shiftEndTime.minute();
int startMinute=shiftStartTime.minute();
int endHour=shiftEndTime.hour();
int subHour,subMinute;
if(endMinute>=startMinute)
{
subHour=endHour-startHour;
subMinute=endMinute-startMinute;
if(subMinute>=60)
{
subMinute-=60;
subHour++;
}
}
else
{
subHour=endHour-startHour-1;
subMinute=endMinute+60-startMinute;
if(subMinute>=60)
{
subMinute-=60;
subHour++;
}
}
allHours-=subHour;
allMinutes-=subMinute;
这是修改按钮按下之后的事情,就是记录一下被修改这个时间段有多长时间,然后把这段扣掉
//以下代码的功能是实现当天总时长的更新--------------------------------------------------当天时间过了十二点自动清空功能未实现
int startHour=startTime.hour();
int endMinute=endTime.minute();
int startMinute=startTime.minute();
int endHour=endTime.hour();
if(endMinute>=startMinute)
{
allHours+=endHour-startHour;
allMinutes+=endMinute-startMinute;
if(allMinutes>=60)
{
allMinutes-=60;
allHours++;
}
}
else
{
allHours+=endHour-startHour-1;
allMinutes+=endMinute+60-startMinute;
if(allMinutes>=60)
{
allMinutes-=60;
allHours++;
}
}
QString hour=QString::number(allHours);
QString minute=QString::number(allMinutes);
ui->hourShowEdit->setText(hour);
ui->minuteShowEdit->setText(minute);
这段和新建的一样了,因为被修改的已经被扣掉了,所以完全相当于再新建了一个
篇末总结
这个板块的功能我实现得非常顺,为什么呢?当已经梳理清楚逻辑关系之后,敲代码反倒是简单的事情了。重要的是思想,而这个思想又要和计算机相符合
沉浸在项目中时不会察觉外界的变化,我完成了这篇博客时才发现自我打开电脑已经过去了五个小时,根本就察觉不到时间过那么快。
程序员面对的就是无穷无尽的困难和弯路,只有多做才能越来越好,不断积累项目经验才能成为优秀程序员。
这个项目的客户端全程是我自己实现的,辅助我的只有Qt基础教学的网课和学长的一句提点,以及AI告诉我的库函数。从需求文档到代码结构到具体实现都是我来做的。感觉自己摸索很慢很歪但是能学到很多东西,笔者后续学java就不用这样了,毕竟java的资源可是细致又全面的
最后说一下笔者对编程实质的一点愚见:编程就是为了更好地实现增删改查。数据结构和算法是为了提高速度,微服务、高并发等最终目的也是为了更好地实现增删改查,而一个程序员的水平就是由这些增删改查的优化来决定的