In English

Показометры в студию!

10.06.2014, Калошин Вячеслав
Ссылка на запись:
http://blog.kaloshin.ru/2014/05/14/

Показометры в студию!
Что первым делом должна делать программа для учета личных финансов? Конечно, показывать нам эти самые финансы. Или, говоря другими словами, показывать состояние счета и транзакции по нему.

vsemo_stage3.png

Счета у нас внутри базы представляют собой классическое дерево, где у каждой веточки есть свой id и id ветки, из которой она растет. Или id и parent_id. Если parent_id=0, то считаем, что этот счет «корневой» и находится на самом верху.

Методов отображения таких деревьев – уйма. Но я на свою голову решил попробовать применить QTreeView. Обложился документацией, нашел парочку хороших статей на хабре … Казалось бы, бери и делай.

Но фигу. QTreeView в Qt – один из немногих компонентов, который сделан «наотстань». Практически нулевая документация, какие-то шаманские пляски для выполнения тривиальнейших вещей и так далее и тому подобное. А практически все примеры в интернете написаны в духе «это просто, берем готовую модель и вуаля!». А как работает эта модель и почему надо это делать так – ноль.

В общем, потратив впустую пару дней с этими «морделями», я плюнул на эту ерундень, взял обычный QTreeWidget и банальным рекурсивным поиском заполнил виджет. На всякие заморочки со скоростью я решил начхать, ибо я не верю, что у обычного пользователя будет больше 100-200 счетов, а на этом уровне сходится все. На тестах виджет вполне нормально крутил 10 000 счетов без каких-либо пожираний памяти или тормозов процессора.

Что касается размазывания логики по коду, то вроде этого удалось избежать. Все необходимое уместилось в одном классе. В общем, с моделью тут гораздо больше мороки, и код получается гораздо более нечитаемым и не поддерживаемым.

Из того, что не было в предыдущих стадиях, так это только то, что добавилась синхронизация таблички rate, в которой хранятся курсы валют. Тут же всплыла проблема: при синхронизации на немощных компьютерах программа сваливается в Application Not Responding. Надо будет куда-нибудь в синхронизацию воткнуть вызов диспетчера очередей. Сменить алгоритм не предлагать, ибо потом некоторые таблички будут расти и расти …

А вот с окошком отображения транзакций получилось все как по книжкам. Там обычная плоская таблица, поэтому QSqlTableModel пришлась впору. И так как документации, примеров и прочего на порядок больше, то и проблем никаких не было. Почти, но об этом позже.

Через некоторое время я переехал на QSqlRelationalTableModel по одной простой причине: у каждой транзакции есть currency_id, которое отвечает за валюту, в которой сделана транзакция. И чтобы не мучиться, проще заставить модельку саму выбирать с помощью join нужные значения из таблицы currency.

Во всем этом великолепии меня поджидало только две засады.

Первая заключалась в именах таблиц. Все-таки transaction является ключевым словом и просто так qtшный sql не хотел использовать эту таблицу. Попытка заэскепить имя таблицы как [transaction] не увенчалась успехом. Но на мою радость оказалось, что «transaction» вполне себе хороший идентификатор для qt.

Вторая заключалась в том, что поле для join задается его порядковым номером. То есть мне надо считать, под каким порядковым номером выводится нужное мне поле и задавать его. А функции типа findColumn(name) я не нашел. Можно, конечно, поизвращаться самому (db.tables никто не отменял), но пока оставлю в качестве todo на будущее.

Наконец, сделал последний штрих: заставил выводить только те транзакции, которые относятся к выделенному счету. Мелочь через setfilter.


В принципе, максимально минимальный клиент готов. Он умеет логиниться и показывать необходимое. Да, коряво, да, даже без капельки дизайна, но умеет.

Что следующее? А следующим будет причесывание внешнего вида и начало эпопеи по разработке интерфейса. Например, надо сделать так, чтобы на планшетах, десктопах и телефонах в ландшафтной ориентации отображалось как «счета-транзакции». А вот на телефонах в портретной ориентации надо выводить «счета», при тапе на счете выводить отдельное окно с транзакциями. И реализовать «назад».

И тулбарчик на андроидах сверху, а на айфонах снизу! И еще.

Короче, в следующей серии будет гламуризация полученного.