Как стать автором
Обновить

Разработка для Sailfish OS: таймеры и реализация экспорта в файл на примере примере приложения для ведения списка дел

Время на прочтение4 мин
Количество просмотров3.2K
Мы уже писали про опыт разработки нашего первого приложения для мобильной платформы Sailfish OS. Но на этом решили не останавливаться и сразу взялись за второе. Целью было создать приложение, с помощью которого пользователь мог бы вести учёт своего рабочего времени, планировать задачи и предоставлять информацию о проделанной работе, иными словами – разработать персональный мобильный тайм-трекер.

Описание приложения


Приложение, естественно, должно уметь вести журнал задач с возможность сохранения времени, потраченного на них. Желательно было, чтобы время можно было засекать с помощью встроенного таймера, а не только прописывать руками. Кроме этого, планировалась возможность создание текстовых отчетов о проделанной работе, в виде таблиц, с последующей отправкой их работодателю.

Так как разработка самой структуры приложения и его интерфейса уже была описана в предыдущих статьях цикла разработки для Sailfish OS (путь от начала разработки до создания первого приложения вы можете отследить здесь и тут), то в этой статье будет описан только функционал, который отличается от реализованного ранее и наиболее интересен с точки зрения его реализации. В нашем приложении — это таймеры задач и экспорт списка задач.

Таймер


Для измерения длительности работ в приложении используется механизм таймера. Процесс отсчета времени осуществляется с помощью стандартного элемента Qt Timer, у которого выставлен интервал обновления 1000 миллисекунд.

Timer {
  id: stopwatch
  interval: 1000
  repeat: true
  running: true
  triggeredOnStart: true
  onTriggered: {
    if (timerActive) {
      var currentTime = new Date ();
      var differeceInTime = (currentTime.getTime() - previousTime.getTime());
      previousTime = currentTime;
      updateData(differentInTime);
    }
  }
}

function updateData(usec) {
  elapsedTime += usec;
  taskTimerString = getTimeString(elapsedTime);
}

При каждом срабатывании события onTriggered у Timer происходит вычисление времени таймера: из текущего времени вычитается время предыдущего срабатывания. Такая реализация удобна тем, что при выходе устройства из неактивного режима, время корректно будет обновлятся.

Для управления таймером сделаны кнопки Старт и Сбросить. Так же есть возможность поставить активный таймер на паузу. Чтобы сохранить замеренное время достаточно нажать на кнопку Сохранить время, доступную в выпадающем меню. Замер таймера автоматически добавится к текущему времени, потраченному на задачу.



Если пользователь пытается запустить новый таймер, пока активен старый, то будет выведен диалог с возможностью выбрать, как поступить со старым таймером: сбросить данные старого таймера и начать новый, сохранить данные старого таймера и начать новый, перейти к старому таймеру.



Также, если таймер активен, то он отображается на обложке приложения.

Экспорт отчетов




В приложении также реализована функция создания отчетов. Отчет представляет из себя таблицу, содержащую информацию о всех хранящихся в приложении задачах. В таблицу записываются даты начала и окончания задачи, ее название и описание, статус задачи, а также время, потраченное на нее. Список задач берется напрямую из базы данных, при этом задачи выбираются из промежутка, который пользователь сам указывает на экране создания отчетов.

function selectByPeriod(beginning, end) {
  var database = getDatabase();
  queryResult.clear();
  database.transaction(function(transaction) {
    var tasks = transaction.executeSql('SELECT * FROM tasks WHERE startDate >= ? AND finishDate <= ?',  [beginning, end]);
    for (var i = 0; i < tasks.rows.length; i++) {
      var element = tasks.rows.item(i);
      var startDate = new Date (element.startDate);
      var finishDate = new Date (element.finishDate);
      convertDateToUTC(startDate);
      convertDateToUTC(finishDate);
      var idDone = element.taskDone === 0 ? false : true
      queryResult.append({"startDate": startDate, "finishDate": finishDate, "taskName": element.taskName, "taskDescription": element.taskDescription, "taskDone": isDone, "spentTime": element.spentTime});
    }
  })
} 

Есть возможность записывать отчеты в файлы двух типов: csv и html. Выбор формата исходного файла происходит также на экране создания отчетов. Для каждого из типов реализован c++ класс, отвечающий за создание соответствующего файла. Запись в csv файлы осуществляется с помощью текстового потока QTextStream. Для корректного отображения кириллицы используется кодировка Windows-1251.

Q_INVOKABLE void writeLine(QVariantList taskInfo) {
    QTextCodec *utf8 = QTextCodec::codecForName("Windows-1251");
    QTextStream stream(&csvFile);
    QStringList line;
    stream.setCodec(utf8);
    for(int i = 0; i < taskInfo.size(); i++) {
        line << taskInfo[i].toString();
    }
    stream << line.join(",") << endl;
}

HTML отчеты создаются с помощью класса QTextDocument. Для создания таблицы с информацией по задачам используется класс QTextTable. Он позволяет задать стиль таблицы и текста в ней.

Q_INVOKABLE void createDocument(int rows, QVariantList columns) {
    report = new QTextDocument();
    QTextCursor cursor(report);
    table = cursor.insertTable(rows + 1, columns.length());
    QTextCharFormat format;
    format.setFontWeight(QFont::Bold);
    QTextCharFormat cellFormat;
    cellFormat.setBackground(QBrush(Qt::cyan));
    for(int col = 0; col < table->columns(); col++) {
        QTextTableCell cell = table->cellAt(0, col);
        QTextCursor cellCursor = cell.firstCursorPosition();
        cell.setFormat(cellFormat);
        cellCursor.mergeCharFormat(format);
        cellCursor.insertText(columns[col].toString());
    }
    QTextTableFormat tableFormat = cursor.currentTable()->format();
    tableFormat.setCellSpacing(0);
    table->setFormat(tableFormat);
}

Q_INVOKABLE void addRow(int row, QVariantList taskInfo) {
    QTextCharFormat cellFormat;
    cellFormat.setBackground(QBrush(Qt::darkCyan));
    for(int col = 0; col < table->columns(); col++) {
        QTextTableCell cell = table->cellAt(row, col);
        QTextCursor cellCursor = cell.firstCursorPosition();
        cellCursor.insertText(taskInfo[col].toString());
    }
    QTextTableCell indexCell = table->cellAt(row, 0);
    indexCell.setFormat(cellFormat);
}

Заключение


В результате было создано приложение с понятным и простым интерфейсом, которое позволяет легко вести и отслеживать список дел. Из ранее не планируемого функционала была добавлена возможность фильтровать задачи по статусу выполнения, чтобы можно было отсеивать выполненные. Приложение было опубликовано в магазине приложений Jolla Harbour под названием Report Card и доступно для скачивания всем желающим. Исходники приложения доступны на GitHub.

Автор: Максим Костерин
Теги:
Хабы:
+7
Комментарии0

Публикации

Истории

Работа

iOS разработчик
22 вакансии
Swift разработчик
30 вакансий
QT разработчик
7 вакансий

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн