- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
Допустим, хочу добавить новый функционал. Что нужно для этого сделать:
1. Объявить сигнал в интерфейсе интерфейсов (хех). Этот, например, скажет презентеру, что пользователь хочет добавить нового ученика в бд.
void addStudSIG(StudentData newStudent);
2. Объявить одноимённый слот в презентере. Пока всё терпимо.
void addStudSLOT(StudentData newStudent);
3. прихуярить их друг к другу в методе презентера, который отвечает за подписку на сигналы интерфейса
QObject::connect(uI, SIGNAL(addStudSIG(StudentData)), this, SLOT(addStudSLOT(StudentData)));
4. реализуем этот слот, реализация состоит из вызова одного метода ("o_" это указатель на "модель", "o" значит "owl", но это не важно)
o_->addStud(newStudent);
5. объявляем этот метод в "модели"
qint32 addStud(StudentData newStudent); // возвращаемое значение это id новой записи в таблице
6. реализуем, опять вызовом одного метода
sController_.addItem(newStudent); // для каждой сущности в таблице у меня есть controller, который отвечает за её обработку
7. Теперь, просто реализуем метод контроллера средствами подключённой ормки, если контроллер есть.
Если нет, то нужно ещё немного покопипастить своего кода.
Т.е. "бизнес-логика" размазана по этим контроллерам. Такая архитектура порождает кучу проблем. Копирую имена методов, чтобы создавать методы.
А если хочешь узнать, что же делает сигнал и тебе не достаточно комментария над ним, нужно идти в глубь на 3 или 4 слоя по вызовам одноимённых
методов, нихуя не понимая.
Думал, создать для всех этих объектов общий интерфейс и возможностями Qt Creator, чередуя левую и правую кнопку мыши, частично генерировать
код. Но это какая-то абстрактная говнокод-фабрика получится. И лапша из перевызова методов не распутается, пусть даже готовиться эта лапша будет
быстро.
Думал, вместо внедрения контроллеров в модель, пронаследовать моделью все эти контроллеры и спокойно вызывать методы. Но 4 предка у одного
класса показалось мне диковатым.
У меня ощущение, что я как ооп-обезъяна забил трюм ненужными классами и потонул. Может не нужно было явно выносить model, view, presenter
в классы? Может не нужно было делать классы для контроллеров, а сделать процедуры в отдельном файле? Слишком много "может".
Я доделал это. Оно злобно рычит, но работает. Но я не хочу каждый раз так задрачивать кнтрлц/кнтрлв. Любой фидбек поможет.
Заранее спасибо. Прикрепляю заголовочники упомянутых классов, сколько влезет.
// абстрактный класс, родитель для любого интерфейса
class UserInterface : public QObject
{
Q_OBJECT
public:
UserInterface();
// методы для обновления интерфейса
virtual void update(данные для обновления интерфейса) = 0;
// далее куча подобных методов
// сигналы сообщают Presenter-у, что произошли изменения в интерфейсе и передают данные от пользователя на дальнейшую обработку
signals:
void addStudSIG(StudentData newStudent);
// далее куча сигналов
};
// назвал presenter чертом
class Daemon : public QObject
{
Q_OBJECT
public:
// подписаться на все события (сигналы) интерфейса пользователя, запомнить указатели на представление и модель
void listen(UserInterface *uI, Owl *o);
// чтобы узнать, что делает слот, смотри одноимённые сигналы UserInterface
public slots:
void getStudsByGradeSLOT(qint32 grade);
// далее куча слотов
private:
// указатель на интерфейс
UserInterface *uI_;
// указатель на модель (бизнес-логику)
Owl *o_;
// прихуярить все сигналы uI к слотам Daemon
void connectSiWithSl_(UserInterface *uI);
};
// это "модель"
class Owl
{
public:
Owl();
~Owl();
void addStud(StudentData s);
// далее все возможные преобразования над бд, owl получился что-то вроде фасада над конкретными контроллерами
// создание бд, открытие и закрытие соединения
void initDb_();
void close_();
private:
// контроллер, отвечающий за создание бд и открытие, закрытие соединения...
BasicDquestDbController bController_;
StudentController sController_;
// далее по контроллеру на каждую сущность базы данных
};
Ахой, матросня! Сегодня с вами капитан Кьют и мы будем бороздить просторы говноморей в поисках код-ревью. Пишу сейчас проектец на Qt. Нас на палубе 2 говнокодера. И я близок к тому, чтобы килевать самого себя. У кого есть время и желание, жду от них совета, а те, кто не захочет помочь, сможет поугарать над начинающей c++ макакой.
В двух словах о проекте: несложное приложение, работает с локальной бд на SQLite через ормку какого-то случайного азиата с гитхаба, интефейс на Qt-шных формах. Архитектурно попытался изобразить MVP. Почему его? Интерфейс нужно было отделить от всего остального. Разработка интерфейса выделилась в отдельную, сложную (и, вроде бы, интересную) задачу. Ею занимаюсь не я. Я отвечаю за "presenter" и "model". Наверное, можно это назвать бекендом. И, чтобы каждый раз не тратить несколько минут на сборку проекта, (все эти ебучие виджеты) я имею заглушку интерфейса. Так вот, братва, я где-то проебался. Нахуярил классов и проебался. Заметил за собой, что при добавлении каждой новой фичи (при готовом скелете архитектуры) снова и снова копирую и вставляю одноимённые функции в одноимённые функции...
Antervis 24.01.2017 06:24 # +1
Во-вторых, для реализации моделей в Qt есть несколько классов-моделей QAbstract*Model. Наследуйся, переопределяй методы, получай модель, выхлоп которой тривиально подается в различные виджеты и QML - компоненты.
В-третьих, ты уверен, что со всеми этими интерфейсами ты сэкономил время?
PascalOverlord 24.01.2017 18:15 # 0
* Это мой второй проект на Qt. Сейчас я им пользуюсь неуверенно и, как видишь, быдлокожу немного (много).
Я пользуюсь Qt 5.6. Либо там ещё не поддерживается новый синтаксис сигналов и слотов, либо я не в ту сторону читал документацию. Поищу инфу про новый синтаксис.
* Про модели в Qt не знал. Потому и понаделал своих моделей. Пойду смотреть про упомянутые классы.
* Вот именно, что не сэкономил. Я потратил кучу времени на то, чтобы их сделать. И пусть, они и удовлетворяют каким-нибудь требованиям инкапсуляции и отделения, расширять их очень заёбно.
Пойду, короче, дальше курить документацию. Теперь хотя бы знаю, что искать, спасибо.
defecate-plusplus 24.01.2017 21:41 # 0
> Qt
но зачем? собрался на пердоликсе запускать?
guest 24.01.2017 22:16 # 0
barop 24.01.2017 22:49 # +2
PascalOverlord 25.01.2017 02:32 # 0
barop 25.01.2017 02:34 # +1
huesto 25.01.2017 02:35 # +7
barop 25.01.2017 02:46 # +1
ну и вообще там же своя атмосфера
свои API для всего
свой QML или как там его
PascalOverlord 25.01.2017 02:51 # +1
Antervis 25.01.2017 06:17 # +2
а ты не завидуй
defecate-plusplus 24.01.2017 23:28 # 0
на календаре сейчас 2017 год, проверь
inkanus-gray 24.01.2017 23:33 # 0
defecate-plusplus 24.01.2017 23:47 # +4
Если это крестоподелие не собирается покорять неизведанные дали в виде настольного пердоликса или гейос-икс, то кутэ нужно закопать там же, где его зачем-то эксгумировали
Всякую годную рожь на MVC с нормальными абстракциями, ОРМ, DI, нормальным UI под шиндошс нужно писать на WPF (особо упоротые могут теребонькать UWP), а сишарп даже JS-питушок учит за месяц в достаточном объеме - принципы фронта то одинаковые, если ты не пыхоимбецил
barop 25.01.2017 00:51 # 0
MVVM же;) В WPF все про него говорят.
PascalOverlord 25.01.2017 02:31 # 0
Если пишешь под винду, то всё, кроме сишарпа есть извращение, ты считаешь? А кьют не стоит трогать, если прога не кросплатформенная? Наверное, учту.
И спасибо за ответы.
Ну и что, что паскаль-оверлорд. Я мог хоть SuperAssassin1999 назваться, прогать от
этого я лучше бы не стал.
barop 25.01.2017 02:35 # 0
1) Под винду если можно писать на сишарпе, то лучше писать на сишарпе
2) Если можно делать гуи на WPF, то лучше делать их на WPF
guestinho 25.01.2017 02:40 # 0
barop 25.01.2017 02:45 # 0
Вообще можно написать веб-приложение под виндуос на дельфи чтобы там была SQL инъекция как на пхп?
ps: блядь, они реально написали CGI на делфьи
http://www.codenet.ru/progr/delphi/stat/webd.php
PascalOverlord 25.01.2017 02:50 # 0
barop 25.01.2017 02:53 # 0
PascalOverlord 25.01.2017 02:52 # 0
Спасибо.
barop 25.01.2017 02:57 # 0
PascalOverlord 25.01.2017 02:59 # 0
Просто, когда в жизни написал 1.5 программы, выбор инструментов больше наудачу происходит.
barop 25.01.2017 03:06 # 0
с другой стороны изучать С++ тоже полезно
huesto 25.01.2017 03:17 # 0
Если с qt, то не факт.
PascalOverlord 25.01.2017 03:19 # 0
Я же не пользуюсь stl. Я даже вместо int пишу qint32; это, вроде, дефайн int, но гипотетический qt погроммист и строчки на чистых плюсах не напишет.
О, господин Хуесто то же самое говорит.
О, господин Хуесто исчез.
Antervis 25.01.2017 06:58 # +1
п.с. зачем писать qint32 когда можно писать через стандартный int32_t? Во-первых, сразу наглядно видно, где важен фиксированный размер поля, во-вторых, переводить с Qt на чистые плюсы может быть проще (да, бывают такие задачи)
PascalOverlord 25.01.2017 03:24 # 0
Я слышал ещё про Руст. По мощности близок с крестам, но не стреляет по ногам. Этот проект пока на стадии размышлений...
PascalOverlord 25.01.2017 03:42 # 0
inkanus-gray 25.01.2017 11:38 # 0
defecate-plusplus 25.01.2017 13:06 # +1
И если уж тормозит 2д гуй, то что говорить о качестве бизнес-функций этого софта на данной машине.
Ну а случаи разные бывают.
Так-то у нас есть заказчик, который не может соскочить с "документооборота" на Лексикон.
barop 25.01.2017 15:16 # 0
Евангелисты от MS говорят: ".net джитица под конкретный CPU и работает более быстро, чем натиывный код под дженерик 686"
зы: кстати, если тормозит то надо посцать на GDI и юзать Direct2D.
Он умеет рисовать прямо в GPU
guestinho 25.01.2017 16:01 # +2
barop 25.01.2017 17:00 # 0
huesto 25.01.2017 17:27 # 0
barop 25.01.2017 17:42 # 0
ради этого и задумали поколения, тащемто
inkanus-gray 26.01.2017 00:45 # +2
Включи NGEN
@
Почувствуй себя гентушником, вечно собирая «нативные образы».
barop 26.01.2017 00:48 # +3
inkanus-gray 24.01.2017 23:48 # 0
PascalOverlord 25.01.2017 02:32 # 0
barop 25.01.2017 02:56 # 0
inkanus-gray 25.01.2017 11:39 # 0
defecate-plusplus 25.01.2017 13:18 # +4
Хотя задачи то решались так се, простецкие. Кнопочки с надписями и рисунками, текстовое поле.
Последней каплей стали анальные проблемы с обработкой 150%, 200% и прочего масштабирования в винде.
В итоге переписав целиком тот модуль на кутэ вышло экономнее, чем продолжать ебаться с wxwidgets.
Xom94ok 25.01.2017 18:32 # 0
когда и если обожжетесь о qtquick - расскажете, хорошо?
bormand 25.01.2017 18:35 # +1
Ну оно же совсем не для энтерпрайзной опердени...
А няшная хуйня с кастомным дизайном на нём неплохо лепится. Мне понравилось.
defecate-plusplus 25.01.2017 19:25 # +4
Оконный С++ это в принципе та ещё клоака. В кутэ нырять - только в погоне за кросс-платформенностью помноженной на обязательность нативного толстого приложения. Таких задач, откровенно говоря, маловато попадается (и слава богу). У нас всего 1 (один) проект, где такое интересно, да и то он внутренний. (Могу по секрету сказать, что это вообще Браузер (oh shi), и там кутэ нужно только так, организовать нескучную примитивную оболочку над CEF под основные оси - менюбар, онскрин кейборд, табы).
В остальном достаточная ынтерпрайзная кросс-платформенность достигается SPA веб-приложениями, которые тупо и неприхотливо работают в любом современном браузере под любой ОС, плюс заодно мобильные девайсы. Мы там даже 3d на webgl успешно применяли. При этом, такие приложения не надо даже деплоить и сопровождать/обновлять на клиентских устройствах - клиент всегда получает последнюю версию для использования, что очень заебись и экономит дохуя денег и нервов.
Толстое приложение само по себе редко требуется - у нас есть и такие проекты. Спасает то, что понятно, что приложение будет работать вот конкретно в шиндошс, и даже можно некие требования наложить на современность этого шиндошс. Тогда, конечно, WPF, нехер думать. Но тут, конечно, и все недостатки толстого приложения, не только достоинства.
Ну и касательно qtquick - годно, это вообще правильная тема разделять представление от данных. В том же WPF или Xamarin приличная доля проекта - разметка вьюх на XAML. Если ты всё ещё в раздумьях учить/юзать или нет - тут других мнений быть не может, конечно брать.
Xom94ok 25.01.2017 20:29 # +2
> в погоне за кросс-платформенностью
Именно за кроссплатформенность и взяли Qt. В военку понемногу внедряют линукс в виде эльбруса, astra, МСВС (упаси Аллах), QNX Neutrino и у начальства появляются охуи восхитительные идеи: "А давайте скомпилируем наше нечто на очередной порезанный военный линукс".
Больше всего приложения похожи на встроенные, запускающиеся в киоск-режиме; некритичные элементы систем могут снабжаться акустическими сенсорными дисплеями, поэтому пилить интерфейсы на QtQuick выглядит более логичным, чем на виджетах.
Однако, сколько я ни пытался нырнуть в эту прорубь, все попытки заканчиваются тем, что я погружаю пальчики задней лапы и валю обратно в виджеты.
> правильная тема разделять представление от данных
QML и QtQuick с той же мыслью рекламируются - отделение представления от данных и программиста от дизайнера. И сделано прокидывание нативного кода в QML весьма удобно, но стоит отойти от примеров - появляются проблемы. Нужно прокинуть список объектов из C++ в QML? Пиши прокси-модель. Редактировать элементы списка в удобной формочке? Дописывай обвязку на JavaScript в сотни строк, ищи узкие места, чтобы интерфейс не тормозил и не прыгал. Таблицы? У QtQuick их не было до недавних пор, всё сырое. Наследовать стандартный контрол тоже нельзя по причине приватности их C++ классов. Документация разрозненная, версионирование упоротое. Это всё мелочи, но из них складывается впечатление эскизного проекта кучки недавних студентов, который почему-то продают уже шесть лет.
> Если ты всё ещё в раздумьях <...> конечно брать
Я, конечно, ещё погуляю по граблям и шишек понабиваю, быть может, я просто лошара и не понял сути QtQuick, но сомнения пока что придержу у себя.
barop 26.01.2017 00:04 # 0
Мне кажется это уже везде так. Гуи надо писать декларативно, причем лучше даже так, чтобы был отдельный инструмент (blend, например).
Даже для свинга есть формбилдеры у интеллиджа.
huesto 26.01.2017 00:18 # 0
barop 26.01.2017 00:22 # +1
Antervis 26.01.2017 06:32 # 0
Antervis 26.01.2017 06:29 # +1
Необязательно. Можно прокинуть QVariantList вручную, можно сделать Q_PROPERTY типа QVariantList (очень прикольная тема кстати - вьюхи могут вместо модели принимать QList объектов и работать так же), еще забыл как, но можно сделать проперти типа "список объектов с пропертями".
> Редактировать элементы списка в удобной формочке?
А ты в QAbstractItemModel::setData не заглядывал?
У меня сейчас один из проектов достаточно крупный, с огромной долей интерфейса на QML. Пока что мой вердикт - QML ОЧЕНЬ хорош, если знать, как им правильно пользоваться. Лично я "стукнулся" только об одну фигню: QML Map не умеет вращаться, причем судя по исходникам, эту фичу убрали, потому что не знали как поддерживать её с тайлами
Xom94ok 26.01.2017 07:15 # 0
Модели добавляется свойство типа QQmlListProperty, которое подключается моделью к списку. Это выглядит как хорошее решение для неизменяемых списков, если же начать добавлять, удалять или перемещать элементы списка, то нужно сообщать об этом вьюхе сигналом NOTIFY listChanged, при этом у списка теряется выделение элементов, скролл и он полностью перерисовывается. Это вообще не вариант.
> А ты в QAbstractItemModel::setData не заглядывал?
Заглядывал. Чтобы получить от ListView вменяемое поведение при каких-либо изменениях крестовой модели, к нему нужно подключать QAbstractItemModel. Сам ListView в реализации не подключает к себе модели напрямую, а использует недокументированный класс посредника (QQuickItemModel, вроде), который отображает сигналы QAbstractItemModel::rowsMoved и другие в понятные вьюхе события. Это выглядит как лучший способ прокидывания модели в QML, для которого нужно писать портянку switch(role) { case case case case case } в пяти местах, что совсем не привлекает.
> мой вердикт - QML ОЧЕНЬ хорош
Мне он тоже нравится, собственно потому и продолжаю жрать кактус и пытаться обходить подводные камни.
Antervis 26.01.2017 07:57 # 0
Значит, ты не настолько тривиальную вещь хочешь сделать, чтобы можно было обойтись без с++-модели
bormand 25.01.2017 18:00 # 0
guest 24.01.2017 12:19 # +1
/тхреад
Steve_Brown 25.01.2017 13:38 # 0
PascalOverlord 25.01.2017 22:54 # 0
Steve_Brown 26.01.2017 11:23 # +6
stud - жеребец
stable - конюшня
A man was hospitalized with 6 plastic horses up his ass... The doctor described his condition as stable.
Steve_Brown 26.01.2017 11:29 # 0
roman-kashitsyn 26.01.2017 12:51 # +1
Как будто это что-то хорошее
barop 26.01.2017 15:18 # 0
guest 04.02.2017 22:03 # 0
ASD_77 15.03.2017 19:48 # +1
barop 15.03.2017 20:04 # 0