Уважаемые, если у кого есть время, желание итд, пожалуйста просмотрите проект домашней бухгалтерии https://github.com/Sheridan/HAcc
В логику можно не вникать, мне хочется знать что там может быть не так, неправильно, или некрасиво.
Спасибо заранее
Здравствуйте, Sheridan, Вы писали:
S>Уважаемые, если у кого есть время, желание итд, пожалуйста просмотрите проект домашней бухгалтерии https://github.com/Sheridan/HAcc S>В логику можно не вникать, мне хочется знать что там может быть не так, неправильно, или некрасиво.
Про логику
1. Зачем синглетонов напихал?
2. Здесь <HAcc / trunk / src / model> чего такое???
file ccontractors.cpp April 21, 2011 Создание и редактирование валюты [Sheridan]
Как получается, что контрагенты создают и редактируют валюты?
3. Здесь <HAcc / trunk / src / model / ccurrencyes.h>
S>Уважаемые, если у кого есть время, желание итд, пожалуйста просмотрите проект домашней бухгалтерии https://github.com/Sheridan/HAcc S>В логику можно не вникать, мне хочется знать что там может быть не так, неправильно, или некрасиво. S>Спасибо заранее
выражение m_actions[atype][id] повторяется дважды-трижды (в зависимости от ифа), а ведь это каждый раз двойной поиск по мапам, т.е. операция совсем небыстрая в общем случае.
Плюс непонятно, что будет, если generateAction() вернет NULL, если такое может быть, конечно.
S>Уважаемые, если у кого есть время, желание итд, пожалуйста просмотрите проект домашней бухгалтерии https://github.com/Sheridan/HAcc S>В логику можно не вникать, мне хочется знать что там может быть не так, неправильно, или некрасиво. S>Спасибо заранее
1) Не понравилась конвертация string->money,amount. Надо использовать QLocale::decimalPoint, ну и плюс хранение денег просто в double без отдельного класса, это та еще головная боль при поиске копеек.
2) Много макросов.
3) Не внятное владение указателями на объект в CFileDialogs
QFileDialog *CFileDialogs::fileDialog(...)
{
QFileDialog *dlg = new QFileDialog(HACC_WINDOW);// у dlg как я понимаю есть родитель
}
SFileDialogResult CFileDialogs::getOpenFileName(const QString &title, const QString &extentions)
{
QFileDialog *dlg = fileDialog(title, extentions);// здесь создали объект и сделали ему родителя
dlg->setFileMode(QFileDialog::ExistingFile);
return execFileDialog(dlg, title, extentions);// здесь на прямую удалили dlg
}
Мне все равно как форматируются исходники и по какому принципу называются классы, но такое встречаю первый раз , ненадолго впал в ступор
4) Заходя в src/model думал будут наследники QAbstractModel.
5) При первом запуске программа не смогла поместится на экран, создавая доки используй tabifyDockWidget.
6) В модальные диалоги передавай parent, чтобы не было лишних движений в (как называется то место где все программы появляются после запуска?) Ну и убери знак (?) в диалогах.
Кроме того в программе присутствуют бесконечные delete, даже для диалогов. В Qt же есть отличный механизм удаления объектов, унаследованных от QObject.
Вот, например:
WAbstractScrollArea::~WAbstractScrollArea()
{
delete m_wArea; // Это лишнее...
}
void WAbstractScrollArea::buildSelfUi()
{
setVerticalScrollBarPolicy (Qt::ScrollBarAsNeeded );
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_wArea = new QWidget(this); // ...потому что m_wArea - наследник QObject
m_wArea->setLayout(m_lArea);
setViewport(m_wArea);
}
Если не нужно наследоваться от QObject, есть ещё QScopedPointer, QSharedPointer.
Здравствуйте, sheep2k, Вы писали:
S>Кроме того в программе присутствуют бесконечные delete, даже для диалогов. В Qt же есть отличный механизм удаления объектов, унаследованных от QObject.
Привык самостоятельно следить за удалением созданного. Отвыкать нет никакого желания, да и опасно, есть шанс в один прекрасный момент выстрелить себе в ногу.
Здравствуйте, VVP, Вы писали:
VVP>Здравствуйте, Sheridan, Вы писали:
S>>Уважаемые, если у кого есть время, желание итд, пожалуйста просмотрите проект домашней бухгалтерии https://github.com/Sheridan/HAcc S>>В логику можно не вникать, мне хочется знать что там может быть не так, неправильно, или некрасиво.
VVP>Про логику VVP>1. Зачем синглетонов напихал?
Надо было в одном все городить?
VVP>2. Здесь <HAcc / trunk / src / model> чего такое??? VVP>
file ccontractors.cpp April 21, 2011 Создание и редактирование валюты [Sheridan]
Как получается, что контрагенты создают и редактируют валюты?
В коммит попало какоето изменение в указанном файле
VVP>3. Здесь <HAcc / trunk / src / model / ccurrencyes.h> VVP>
Здравствуйте, Sheridan, Вы писали:
S>Привык самостоятельно следить за удалением созданного. Отвыкать нет никакого желания, да и опасно, есть шанс в один прекрасный момент выстрелить себе в ногу.
Как раз самостоятельное удаление — это и есть стрельба себе по ногам. Потому что утечки будут всякий раз при возникновении необработанного исключения.
За освобождением ресурсов должны следить RAII-обёртки.
I>Здравствуйте, Sheridan, Вы писали:
S>>Уважаемые, если у кого есть время, желание итд, пожалуйста просмотрите проект домашней бухгалтерии https://github.com/Sheridan/HAcc S>>В логику можно не вникать, мне хочется знать что там может быть не так, неправильно, или некрасиво. S>>Спасибо заранее
Зачем столько вспомогательных GUI классов? Чем стандартные не угодили? Писал бы на qml я бы еще понял, там с этим не всегда хорошо.
Здравствуйте, jazzer, Вы писали:
J>Плюс непонятно, что будет, если generateAction() вернет NULL, если такое может быть, конечно.
Это обрабатывается несколько позже, в итоге возвращается new QAction("Somewhere bug", 0);
J>checkSpetialPurposeTag -> checkSpecialPurposeTag (и прочие Spetial) J>CSingleTone -> CSingletone J>CTransactionsPools -> CTransactionPools, transactions_pool -> transaction_pool
Fixed.
J>выражение m_actions[atype][id] повторяется дважды-трижды (в зависимости от ифа), а ведь это каждый раз двойной поиск по мапам, т.е. операция совсем небыстрая в общем случае.
По другому практически никак. Смысл в том, что есть действие не существует, оно создается и возвращается. Если существует, то просто возвращается. Типа синглтонов.
Здравствуйте, Igore, Вы писали:
I>Зачем столько вспомогательных GUI классов? Чем стандартные не угодили? Писал бы на qml я бы еще понял, там с этим не всегда хорошо.
Всмысле? Я беру стандартные и компоную из них нужные мне. Например кнопка с выпадающим списком-табличкой и индикацией выбранного на кнопке.
Здравствуйте, Igore, Вы писали:
I>1) Не понравилась конвертация string->money,amount. Надо использовать QLocale::decimalPoint,
Смысл запятую в точку преобразовать и поудалять все кроме чисел и точки. Зачем лишний вызов?
I>ну и плюс хранение денег просто в double без отдельного класса, это та еще головная боль при поиске копеек.
мысль...
I>2) Много макросов.
Ничего не поделаешь, мне очень удобно с макросами.
I>3) Не внятное владение указателями на объект в CFileDialogs
Согласен, невнятное. Но работает правильно
I>Мне все равно как форматируются исходники и по какому принципу называются классы, но такое встречаю первый раз , ненадолго впал в ступор I>
Смысл — совпадающие части выровнять. Изза этого сразу видно различие между строками.
I>5) При первом запуске программа не смогла поместится на экран,
о0 15"?
I>создавая доки используй tabifyDockWidget.
А, понял. Возможно. Может mdi по умолчанию?
Здравствуйте, Sheridan, Вы писали:
J>>выражение m_actions[atype][id] повторяется дважды-трижды (в зависимости от ифа), а ведь это каждый раз двойной поиск по мапам, т.е. операция совсем небыстрая в общем случае. S>По другому практически никак. Смысл в том, что есть действие не существует, оно создается и возвращается. Если существует, то просто возвращается. Типа синглтонов.
не, это ты не понял.
тебя операторы с толку сбивают, похоже.
давай я перепишу на вызовах функций:
Здравствуйте, jazzer, Вы писали:
J>теперь проблема видна?
Я это понимал и раньше. Терперь давай тебе объясню:
QAction * CBases::constructAction(EActionsTypes atype, const hacc::TDBID &id, QObject *reciever, const char * method)
{
if(В массиве есть элемент?)
{
QAction *gAction = generateAction(atype, reciever, method);
gAction->setEnabled(HACC_DB->isOpen());
connect(HACC_DB, SIGNAL(stateChange(bool)), gAction, SLOT(setEnabled(bool)));
Нету? ок, создаем и добавляем. = gAction;
}
return Теперь есть в любом случае, возвращаем;
}
Имхо любая попытка оптимизации тут приведет лишь к лишним вызовам.
Через отдельную переменную? Ее ндо инициализировать элементом массива, а затем обратно положить в массив если NULL был.
Сделать проверку не на NULL а на contains(id) — в итоге три проверки вместо одной:
Пока что больше вариантов не вижу. Имхо у меня хоть и от двух до трех вызово тяжелых обсчетов, но это самый приемлемый вариант. Проще некуда.
Но предложения выслушаю.
Здравствуйте, Centaur, Вы писали:
C>Как раз самостоятельное удаление — это и есть стрельба себе по ногам. Потому что утечки будут всякий раз при возникновении необработанного исключения.
Необработанное исключение должно подразумевать окошко об ошибке и аварийное завершение программы. Этого у меня тоже, конечно, нет. Но с этой точки зрения утечки — фигня.
Если я правильно понимаю, в финальном мапе у тебя лежат указатели, и вызов m_actions[atype][id] имеет тип QAction*& (ссылка на указатель).
Поэтому надо ее просто закэшировать и дальше пользоваться этой ссылкой, и тогда у тебя будет всего один поиск по мапам:
Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, Igore, Вы писали:
I>>1) Не понравилась конвертация string->money,amount. Надо использовать QLocale::decimalPoint, S>Смысл запятую в точку преобразовать и поудалять все кроме чисел и точки. Зачем лишний вызов?
Замени разделитель в своей локали на другой, и посмотри как будет работать программа, собственно вариантов 2:
а) Используешь свою локаль устанавливая ее перед чтением записью данных
b) Используешь QLocale::decimalPoint
I>>5) При первом запуске программа не смогла поместится на экран, S>о0 15"?
Кхм, 2 монитора, 1-ый 24'', второй 19'', при первом запуске программа по ширине расползлась на 2 монитора. При закрытии программы не было сохранения позиций QWidget.saveGeometry()
I>>создавая доки используй tabifyDockWidget. S>А, понял. Возможно. Может mdi по умолчанию?
Сгруппируй элементы так чтобы пользователь запуская программу мог сразу работать, а не перетаскивать элементы под свое виденье.