- Overview
- Defining a Task
- Add task function
- How to hide and show the finished and the pending tasks
- Save tasks
- Open tasks
- Change the content of an item
- MVC model
- THE END
- In this homework 4 we are trying to create a task manager app to help us to manage your daily tasks easily.
Now we are going to show how to define a task
A Task is defined by the following attributes:
- A description: stating the text and goal for the task like (Buying the milk).
- A finished Boolean indicating if the task is Finished or due.
- A Tag category to show the class of the task which is reduced to the following values:
- Work
- Life
- Other
- Finally, a task should have a DueDate which stores the Date planned for the date.
The result should look like this:
Now , we are adding setters :
- date setter
void addTaskDialog::setdate(int y,int m, int d){
QDate da;
da.setDate(y,m,d);
ui->dateEdit->setDate(da);
}
- description setter
void addTaskDialog::setdesc(QString a){
ui->lineEdit->setText(a);
}
- tag setter
void addTaskDialog::settag(QString a){
ui->comboBox->setCurrentText(a);
}
- checkbox setter
void addTaskDialog::setf(bool a){
ui->checkBox->setChecked(a);
}
- gettext function
QString addTaskDialog::getText(){
QString a= ui->lineEdit->text() + " Due : " + ui->dateEdit->text() + " Tag : " + ui->comboBox->currentText() +"";
return a;
}
Here we are defining a minimum date :
QDate date =QDate::currentDate();
ui->dateEdit->setMinimumDate(date);
ui->dateEdit->setDate(date);
We are adding a slot to our header::
private slots :
void on_action_Add_triggered();
//first we call the task dialog
addTaskDialog dialog;
auto reply= dialog.exec();
if(reply == addTaskDialog::Accepted)
{
//we save the task on a text string using the gettext function
QString text= dialog.getText();
// now based on the date and the checkbox status we will decide on wich listwidget we are going to add our task as an item
if(dialog.getDate()==QDate::currentDate() && !dialog.isChecked()){
ui->listWidget->addItem(text);
}else if(dialog.getDate()!=QDate::currentDate() && !dialog.isChecked()){
ui->lw2->addItem(text);
}else if(dialog.isChecked()){
ui->lw3->addItem(text);
}
}
The user can either hide or show the pending and finished tasks. We are adding the following slots to our header:
private slots:
void on_action_View_pending_tasks_toggled(bool arg1);
void on_action_View_finished_tasks_toggled(bool arg1);
- The execution of on_action_View_pending_tasks_toggled slot
void ToDoApp::on_action_View_pending_tasks_toggled(bool arg1)
{
if(arg1){
ui->lw2->setVisible(true);
}else{
ui->lw2->setVisible(false);
}
}
- the execution of on_action_View_finished_tasks_toggled slot
void ToDoApp::on_action_View_finished_tasks_toggled(bool arg1)
{
if(arg1){
ui->lw3->setVisible(true);
}else{
ui->lw3->setVisible(false);
}
}
This two lines will our widgets invisible by default we have to add them to our constructor
ui->lw2->setVisible(false);
ui->lw3->setVisible(false);
We will create a save function that help us to save our tasks after closing our application :
protected:
void closeEvent(QCloseEvent* e) override;
The tasks will be saved on a .txt file :
void ToDoApp::closeEvent(QCloseEvent* e){
QFile file("C:/Users/hamza/C++/done.txt");
if(file.open(QIODevice::ReadWrite | QIODevice::Text)){
QTextStream out(&file);
for(int i=0;i<ui->listWidget->count();i++)
{
out << "1"<< ui->listWidget->item(i)->text() << Qt::endl;
}
for(int i=0;i<ui->lw2->count();i++)
{
out << "2"<< ui->lw2->item(i)->text() << Qt::endl;
}
for(int i=0;i<ui->lw3->count();i++)
{
out << "3"<< ui->lw3->item(i)->text() << Qt::endl;
}
file.close();
}
}
This code make our tasks entered to our application remains there to use it when ever we want
QFile file("C:/Users/hamza/C++/done.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!file.atEnd()) {
QString line = file.readLine();
if(line.at(0)=="1"){
ui->listWidget->addItem(line.mid(1,line.size()));
}else if(line.at(0)=="2"){
ui->lw2->addItem(line.mid(1,line.size()));
}else if(line.at(0)=="3"){
ui->lw3 ->addItem(line.mid(1,line.size()));
}
}
We need to link the list widget to a function that is automatically executed if a task is double clicked :
connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this,SLOT(v1()));
connect(ui->lw2, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this,SLOT(v2()));
connect(ui->lw3, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this,SLOT(v3()));
We have to add these three slots to the header :
private slots:
void v1();
void v2();
void v3();
The execution of the slots v1():
void ToDoApp::v1(){
addTaskDialog dialog;
int i=1;
QString task;
// declare the new task
QListWidgetItem *a=ui->listWidget->currentItem();
// now we split the task
QStringList list = a->text().split(QRegularExpression("\\W+"), Qt::SkipEmptyParts);
task+=list[0];
while(list[i]!="Due"){
task+=" "+list[i];
i++;
}
// set the date
dialog.setdate(list[i+3].toInt(),list[i+1].toInt(),list[i+2].toInt());
// set the description
dialog.setdesc(task);
//set the tag
dialog.settag(list[i+5]);
auto reply= dialog.exec();
if(reply == addTaskDialog::Accepted)
{
QString text= dialog.getText();
if(dialog.getDate()==QDate::currentDate() && !dialog.isChecked()){
ui->listWidget->addItem(text);
}else if(dialog.getDate()!=QDate::currentDate() && !dialog.isChecked()){
ui->lw2->addItem(text);
}else if(dialog.isChecked()){
ui->lw3->addItem(text);
}
// delete the previous item so we won't have a duplicated one
delete a ;
}
}
Same for the second slot :
void ToDoApp::v2(){
addTaskDialog dialog;
int i=1;
QString task;
// declare the new task
QListWidgetItem *a=ui->listWidget->currentItem();
// now we split the task
QStringList list = a->text().split(QRegularExpression("\\W+"), Qt::SkipEmptyParts);
task+=list[0];
while(list[i]!="Due"){
task+=" "+list[i];
i++;
}
// set the date
dialog.setdate(list[i+3].toInt(),list[i+1].toInt(),list[i+2].toInt());
// set the description
dialog.setdesc(task);
//set the check box for finished tasks to true
dialog.setf(true);
//set the tag
dialog.settag(list[i+5]);
auto reply= dialog.exec();
if(reply == addTaskDialog::Accepted)
{
QString text= dialog.getText();
if(dialog.getDate()==QDate::currentDate() && !dialog.isChecked()){
ui->listWidget->addItem(text);
}else if(dialog.getDate()!=QDate::currentDate() && !dialog.isChecked()){
ui->lw2->addItem(text);
}else if(dialog.isChecked()){
ui->lw3->addItem(text);
}
// delete the previous item so we won't have a duplicated one
delete a ;
}
}
The results :
With Models we are going to make another ToDo App
-
With the Qt Designer and using QListView we are going to create a form :
-
QStringModel help us to create models :
- We put this code to our header
QStringListModel *model1;
QStringListModel *model2;
QStringListModel *model3;
QStringList Todaytasks;
QStringList Finishedtasks;
QStringList Pendingtasks;
model1 = new QStringListModel();
model2 = new QStringListModel();
model3 = new QStringListModel();
```
- After that we need to set the model to the view
```cpp
model1->setStringList(Todaytasks);
ui->lw1->setModel(model1);
model2->setStringList(Pendingtasks);
ui->lw2->setModel(model2);
model3->setStringList(Finishedtasks);
ui->lw3->setModel(model3);
- Add function
void ToDoApp::on_action_Add_triggered()
{
addTaskDialog dialog;
auto reply= dialog.exec();
if(reply == addTaskDialog::Accepted)
{
QString text= dialog.getText();
if(dialog.getDate()==QDate::currentDate() && !dialog.isChecked()){
Todaytasks.append(text);
}else if(dialog.getDate()!=QDate::currentDate() && !dialog.isChecked()){
Pendingtasks.append(text);
}else if(dialog.isChecked()){
Finishedtasks.append(text);
}
}
model1->setStringList(Todaytasks);
ui->lw1->setModel(model1);
model2->setStringList(Pendingtasks);
ui->lw2->setModel(model2);
model3->setStringList(Finishedtasks);
ui->lw3->setModel(model3);
}
- Tthe execution of the new open and save function
- Save :
void ToDoApp::closeEvent(QCloseEvent* e){
QFile file("C:/Users/hamza/Desktop/done.txt");
if(file.open(QIODevice::ReadWrite | QIODevice::Text)){
QTextStream out(&file);
for(int i=0;i<Todaytasks.size();i++)
{
out << "1"<< Todaytasks.at(i)<< Qt::endl;
}
for(int i=0;i<Pendingtasks.size();i++)
{
out << "2"<< Pendingtasks.at(i) << Qt::endl;
}
for(int i=0;i<Finishedtasks.size();i++)
{
out << "3"<< Finishedtasks.at(i) << Qt::endl;
}
file.close();
}
}
- Open :
- this will be added to the constructor
QFile file("C:/Users/hamza/Desktop/done.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!file.atEnd()) {
QString line = file.readLine();
if(line.at(0)=="1"){
Todaytasks.append(line.mid(1,line.size()));
}else if(line.at(0)=="2"){
Pendingtasks.append(line.mid(1,line.size()));
}else if(line.at(0)=="3"){
Finishedtasks.append(line.mid(1,line.size()));
}
}
model1->setStringList(Todaytasks);
ui->lw1->setModel(model1);
model2->setStringList(Pendingtasks);
ui->lw2->setModel(model2);
model3->setStringList(Finishedtasks);
ui->lw3->setModel(model3);
- Change content of a task
- We connect the lists to the slots that perform these actions
connect(ui->lw1, SIGNAL(doubleClicked(QModelIndex)), this,SLOT(v1()));
connect(ui->lw2, SIGNAL(doubleClicked(QModelIndex)), this,SLOT(v2()));
connect(ui->lw3, SIGNAL(doubleClicked(QModelIndex)), this,SLOT(v3()));
- The execution of v1() :
void ToDoApp::v1(){
addTaskDialog dialog;
int i=1;
QString task;
QModelIndex index=ui->lw1->currentIndex();
QString a=Todaytasks.at(index.row());
QStringList list = a.split(QRegularExpression("\\W+"), Qt::SkipEmptyParts);
task+=list[0];
while(list[i]!="Due"){
task+=" "+list[i];
i++;
}
dialog.setdate(list[i+3].toInt(),list[i+1].toInt(),list[i+2].toInt());
dialog.setdesc(task);
dialog.settag(list[i+5]);
auto reply= dialog.exec();
if(reply == addTaskDialog::Accepted)
{
QString text= dialog.getText();
if(dialog.getDate()==QDate::currentDate() && !dialog.isChecked()){
Todaytasks.append(text);
Todaytasks.removeAt(index.row());
}else if(dialog.getDate()!=QDate::currentDate() && !dialog.isChecked()){
Pendingtasks.append(text);
Todaytasks.removeAt(index.row());
}else if(dialog.isChecked()){
Finishedtasks.append(text);
Todaytasks.removeAt(index.row());
}
}
model1->setStringList(Todaytasks);
ui->lw1->setModel(model1);
model2->setStringList(Pendingtasks);
ui->lw2->setModel(model2);
model3->setStringList(Finishedtasks);
ui->lw3->setModel(model3);
}
- The execution of v2() :
void ToDoApp::v2 (){
addTaskDialog dialog;
int i=1;
QString task;
QModelIndex index=ui->lw2->currentIndex();
QString a=Pendingtasks.at(index.row());
QStringList list = a.split(QRegularExpression("\\W+"), Qt::SkipEmptyParts);
task+=list[0];
while(list[i]!="Due"){
task+=" "+list[i];
i++;
}
dialog.setdate(list[i+3].toInt(),list[i+1].toInt(),list[i+2].toInt());
dialog.setdesc(task);
dialog.settag(list[i+5]);
auto reply= dialog.exec();
if(reply == addTaskDialog::Accepted){
QString text= dialog.getText();
if(dialog.getDate()==QDate::currentDate() && !dialog.isChecked()){
Todaytasks.append(text);
Pendingtasks.removeAt(index.row());
}else if(dialog.getDate()!=QDate::currentDate() && !dialog.isChecked()){
Pendingtasks.append(text);
Pendingtasks.removeAt(index.row());
}else if(dialog.isChecked()){
Finishedtasks.append(text);
Pendingtasks.removeAt(index.row());
}
}
model1->setStringList(Todaytasks);
ui->lw1->setModel(model1);
model2->setStringList(Pendingtasks);
ui->lw2->setModel(model2);
model3->setStringList(Finishedtasks);
ui->lw3->setModel(model3);
}
- The execution of v3()
void ToDoApp::v3(){
addTaskDialog dialog;
int i=1;
QString task;
QModelIndex index=ui->lw3->currentIndex();
QString a=Finishedtasks.at(index.row());
QStringList list = a.split(QRegularExpression("\\W+"), Qt::SkipEmptyParts);
task+=list[0];
while(list[i]!="Due"){
task+=" "+list[i];
i++;
}
dialog.setdate(list[i+3].toInt(),list[i+1].toInt(),list[i+2].toInt());
dialog.setdesc(task);
dialog.setf(true);
dialog.settag(list[i+5]);
auto reply= dialog.exec();
if(reply == addTaskDialog::Accepted){
QString text= dialog.getText();
if(dialog.getDate()==QDate::currentDate() && !dialog.isChecked()){
Todaytasks.append(text);
Finishedtasks.removeAt(index.row());
}else if(dialog.getDate()!=QDate::currentDate() && !dialog.isChecked()){
Pendingtasks.append(text);
Finishedtasks.removeAt(index.row());
}else if(dialog.isChecked()){
}
}
model1->setStringList(Todaytasks);
ui->lw1->setModel(model1);
model2->setStringList(Pendingtasks);
ui->lw2->setModel(model2);
model3->setStringList(Finishedtasks);
ui->lw3->setModel(model3);
}
after working on this rapport i learned how to create an app to help you to manage your time easily