Два экземпляра класса — проблема будет при присвоении, никто автоматически вызывать нотификацию об изменении полей не будет, писать руками — опять лишний код.
Вариант с setParam иногда использовал, но тогда пропадает одна из основных фишек QML — bind'инг.
Одно из условий — в процессе редактирования приложение использует старые настройки. В той схеме, что вы описали, нельзя будет bind'ить контролы на свойства модели, иначе в процессе редактирование настройки приложения будут меняться (после изменения состояния отдельного контрола). Поэтому и получается «лишний» класс.
Простой пример. Есть приложение. В приложении есть некоторые настройки. Эти настройки редактируются на отдельной форме. Требуемое поведение: после изменения настроек проверить их совместимость между собой и в случае отсутствия ошибок применить эти настройки для приложения (пока редактируются настройки, приложение работает на старых настройках). В случае ошибок совместимости настройки не применяются (к примеру, выдается сообщение об ошибках, и форма не закрывается). После изменения, настройки сохраняются, к примеру, в файл для восстановления при следующем запуске приложения.
Как я это делаю на чистом Qt. Панель диалога, при инициализации собираются настройки и заполняются соответствующие контролы. При Accept'е формы данные с контролов читаются, проверяются, если все Ок, то данные записываются в текущие настройки приложения, вызывается метод записи текущих настроек в файл.
Как я это делаю в связке Qt/QML. На Qt пишется модель настроек, причем в этом же классе появляются методы: чтение текущих настроек в модель, проверка настроек, применение настроек (запись в текущие настройки + запись в файл). Эта модель экспортируется в подсистему QML. Делается QML форма. В ней контролы bind'ятся на данные модели, в методе onComplete вызывается метод чтения текущих настроек в модель, на клавишу Ok вешается JavaScript код, который вызывает связку проверки и применения настроек.
Итого: в связке Qt/QML появляется лишний класс модели, который по факту ничего не делает. А если настроек много, то кода получается тоже много (на каждое поле настроек по три метода).
Сигналы/слоты, это если у вас только клавиши. Как только появляются поля ввода, то начинаются свойства, с процедурами чтения/установки и т.д. А если нужно передавать список или таблицу, то программного кода получается очень много. В результате на каждую сущность нужно городить модель. И в конце проекта получается этих моделей штук 20-30, иногда больше.
Полностью согласен. Писать легко, контролы получаются красивыми и быстрыми, минимум кода. Именно это и подкупает в начале проекта. Но связка Qt с QML в итоге занимает много кода и времени. Возможно если всю логику проекта перегнать на сторону QML (под JS) это будет большой проблемой. Но когда логика на C++, а на QML только интерфейс, то для меня это проблема.
В том-то и дело, что сначала кажется, что кода мало. А потом он начинает плодится и занимать % 20 от всего проекта. Да, в начале проекта QML позволяет быстро сделать красивую картинку, но с ростом проекта выгода от него начинает уменьшаться. В результате начинаешь думать, что лучше бы потратил время на написание собственных контролов в Qt в начале проекта.
Сделал 5 полноценных проектов в связки QML/Qt за последние лет 7. И в конце каждого проекта понимал, что лучше бы сделал на чистом Qt. Код для связки Qt и QML получается слишком большой. Быстро надоедает его писать.
Читал «Mastering Bitcoin» — отличная книга. А нет ли что-то похожего для Ethereum? Чтобы со структурами данных (с ними легче понимать происходящее) и описанием внутренних алгоритмов.
Два крайних подхода. 1. Если что-то можно сделать в языке без ввода новых конструкций, то новую конструкцию не вводят. 2. Вводить новую конструкцию по любому мелочному поводу.
Истина где-то посередине. Но середина у всех разная. У меня она ближе к пункту 1.
Про разделения struct и class я говорил (увы не уточнил) в контексте, как надо было сделать, когда вводились классы. Сейчас, понятно, это сделать уже нельзя.
Насчет { } немного долгое объяснение. Когда-то очень давно, когда в C++ вводились классы их синтаксически приравняли к структурам. Но в моей реальной практике (и не только в моей) слово class используют, когда нужен полноценный объект, а слово struct, когда нужны только переменные члены класса (и они все открытые). В struct практически не пишутся функции, иногда пишется конструктор, еще реже деструктор. И вот именно дефолтного конструктора по всем членам структуры мне всегда не хватало. Скобки { }
решают это проблему, но заодно вводят путаницу в вызовы конструкторов. По мне, так правильней было бы разделить назначение struct и class. И как минимум сделать дефолтный конструктор для struct по списку членов.
Полностью согласен. Посмотрите на грамотные java.io.InputStream, java.io.OutputStream. А вот зачем было ввод и вывод мандить в std::ios? И зачем были нужны операторы << и >>. В реальных проектах они неудобны, сложно настраивать форматирование, невозможно делать локализацию и т.д. printf по сравнению с ними просто сказка.
У меня стойкое чувство, что iostream (и друзья) спроектированы по двум причинам: оправдать наличие в языке виртуальных классов (ромб смерти) и показать как здорово можно переопределять операторы (в данном случае << и >>). А для того чтобы показать на примере специализацию шаблонов специализирован класс std::vector. И т.д. и т.п.
Думаю будет полезно определение [[maybe_error]] — если функция не используется, то может содержать ошибки (не компилироваться). Извините за черный юмор.
Вариант с setParam иногда использовал, но тогда пропадает одна из основных фишек QML — bind'инг.
Как я это делаю на чистом Qt. Панель диалога, при инициализации собираются настройки и заполняются соответствующие контролы. При Accept'е формы данные с контролов читаются, проверяются, если все Ок, то данные записываются в текущие настройки приложения, вызывается метод записи текущих настроек в файл.
Как я это делаю в связке Qt/QML. На Qt пишется модель настроек, причем в этом же классе появляются методы: чтение текущих настроек в модель, проверка настроек, применение настроек (запись в текущие настройки + запись в файл). Эта модель экспортируется в подсистему QML. Делается QML форма. В ней контролы bind'ятся на данные модели, в методе onComplete вызывается метод чтения текущих настроек в модель, на клавишу Ok вешается JavaScript код, который вызывает связку проверки и применения настроек.
Итого: в связке Qt/QML появляется лишний класс модели, который по факту ничего не делает. А если настроек много, то кода получается тоже много (на каждое поле настроек по три метода).
Истина где-то посередине. Но середина у всех разная. У меня она ближе к пункту 1.
Про разделения struct и class я говорил (увы не уточнил) в контексте, как надо было сделать, когда вводились классы. Сейчас, понятно, это сделать уже нельзя.
решают это проблему, но заодно вводят путаницу в вызовы конструкторов. По мне, так правильней было бы разделить назначение struct и class. И как минимум сделать дефолтный конструктор для struct по списку членов.