LINUX.ORG.RU
решено ФорумTalks

Слон-художник это я

 , ,


2

1

Итак, по просьбе ass я выкладываю эскиз слоновьей живописи под рабочим названием Project Tritium вот.

В нём я периодически, в свободное время, пытаюсь сделать нормальную многопрофильность в Trojita

Пока получается хрень)

Теперь к технической части.

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

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

А теперь первый вопрос: я на самом деле не понял, каким образом строка из объекта настроек QSettings станет доступна в нашей структурке AppSettingsNames ?

Временно для этого члена структуры я захардкодил имя профиля, для проверки. Что привело меня к вопросу №2: Как можно разделить настройки приложения? Если оно их считывает одним махом из объекта настроек.

Резюмируя вышенаписанное, основных вопросов к сообществу 2

  • Как правильно разделить настройки приложения и настройки ящика? Попутно избавиться от всякой ереси вроде глобальных переменных, но не нагородить преждевременно при этом синглтонов вокруг QSettings. А сам QSettings будет хранить только одну настройку — имя активного профиля. Это не годится.
  • Как заставить приложение использовать эти настройки отдельно друг от друга?

Тему лаунчера решил пока отложить — тут интереснее

Из положительного, эта мазня собирается, да :-)

К модератом, пишу в толксы, чтобы помидоры кидали в меня только регистранты.

Найдёте нужным, переносите в Development.

Надеюсь, что коллективный разум наставит меня на путь истинный.

Всем спасибо за внимание!

★★★★★

QSettings

Он сам внешне чем-то на синглтон похож, если кастомный файл настроек не указываешь. Так что смело добавляй везде соответствующий хедер и, где надо, дёргай QSettings::value().


Как правильно разделить настройки приложения и настройки ящика?

QSettings::beginGroup()/QSettings::endGroup(). В отдельной группе — настройки приложения, в том числе активный профиль, в остальных — настройки профилей

XMs ★★★★★
()
Ответ на: комментарий от Rastafarra

Линии поступательного развития личностных и профессиональных качеств)

Twissel ★★★★★
() автор топика

каким образом строка из объекта настроек QSettings станет доступна в нашей структурке

Путем присвоения.

Как правильно разделить настройки приложения и настройки ящика?

Не писать ящики в сеттингс, вестимо. А писать их в отдельный файл, хош JSON, хош XML, хош что-то еще.

нагородить преждевременно при этом синглтонов вокруг QSettings

Зачем? У тебя же там однопоточное приложение.

deep-purple ★★★★★
()
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

Зачем? У тебя же там однопоточное приложение.

Ну просто есть устоявшаяся практика заменять глобальные переменные синглтоном.

Но я сразу написал, что это не тот случай, когда такое оправдано.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

устоявшаяся практика

Устоявшимся заблуждением является фраза «глобалы это зло». Хотя без глобалов жить не получается. А уже за этим поехала и практика. Придумали дополнительных приключений на жопу из-за придуманной хери. В многопоточке это оправданно, однако, метастазы добрались и до однопоточек.

deep-purple ★★★★★
()
Ответ на: комментарий от DELIRIUM

Нуу писал) Но дело вот в чем, там и так конфиг немаленький и уже с кучей секций (групп). Просто хотелось его разбить на два и сделать красиво. Но сразу красиво не получится))

А вообще да, надо задуматься над тем, чтобы потом вынести конфиги ящиков в XML

Twissel ★★★★★
() автор топика
Ответ на: комментарий от DELIRIUM

JSON

Тогда уж YAML. Бесит в JSON-е постоянно кавычки расставлять

XMs ★★★★★
()
Ответ на: комментарий от Twissel

XML не для пользовательского софта. Конфиг должен спокойно редактироваться руками, желательно не вызывая острого желания всё удалить.

А то будет у тебя софтина падать на разборе конфига по каким-либо причинам, что пользователь будет делать?

ЗЫЖ Бери toml.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Ну ок, мне бы пока с элементарным разобраться. Пока остановимся на текством, т.к. все говно: XML, JSON и т.д. toml посмотрю, но можешь показать примеры, кто его использует?

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

toml посмотрю, но можешь показать примеры, кто его использует?

TOML это и есть QSettings .ini на стероидах.

Ничего крутить не нужно, использовать нужно то, что все давно уже используют в Qt-проектах.

EXL ★★★★★
()
Ответ на: комментарий от DELIRIUM

Я задал наводящий вопрос)

Зачем мне провоцировать нездоровую полемику на пустом месте из-за какого-то маргинального формата))

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Пока остановимся на текством

Весьма разумный выбор.

можешь показать примеры, кто его использует?

Солидарен с нижеотписавшимися. Никому он не нужен.

Из известного только cargo и pip. Но если сравнивать между toml и xml, мне, как пользователю, первый будет намного приятней и понятней. В сравнении с json'ом тоже. С yaml в принципе не важно, но toml чуть более интуитивен, имхо.

Короче, главное, чтоб не xml. Ну не для десктопа он.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от XMs

Просто тогда большой и путанный конфиг получится.

У меня все равно пока картинка до конца не складывается.

Здесь задаются настройки, а тут используются в программе. Так вот если в первом случае, еще понятно, что (я так думаю) можно сделать отдельный метод void

GeneralPage::appsave(QSettings &s)
то как дважды проинициализовать приложение, чтобы иметь при этом два конфига и два объекта настроек, я не пойму)

Twissel ★★★★★
() автор топика
Ответ на: комментарий от XMs

Хотя правильнее всего, наверное, начать именно с выдирания настроек IMAP в отдельные сущности.

Короче все оказалось сложнее, чем я предполагал.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

void GeneralPage::save(QSettings &s)

К слову, ты смело можешь создавать экземпляр QSettings прямо в функции, он будет писать в дефолтный конфиг. Ну это так, на всякий случай.


то как дважды проинициализовать приложение, чтобы иметь при этом два конфига и два объекта настроек, я не пойму)

Не вижу прям большой необходимости держать два конфига, но если очень хочется, то в чём проблема создавать помимо обычного QSettings() какой-нибудь QSettings(const QString &fileName, QSettings::Format format, QObject *parent = nullptr)? Но это плохо минимум по двум причинам:

  1. Тебе придётся руками разбираться с путями и прочей морокой, да и вообще инициализировать сложнее;
  2. Прощай, нормальная кроссплатформенность. На тех же форточках приложения должны хранить свои настройки в реестре, а не в файле.

Поэтому мне кажется лучшей идеей хранить всё в одном файле. Ну или, если уж так хочется, в какой-нибудь sqlite-базе.


Хотя правильнее всего, наверное, начать именно с выдирания настроек IMAP в отдельные сущности

Я не в курсе, как у вас там устроено это дело изнутри, но, как мне кажется, тебе стоит выделить в отдельные сущности:

  • Настройки приложения (пути, единицы измерения, всё, что используется приложением, но не гуёвое);
  • Настройки окон;
  • Настройки профилей, если оно у вас есть (я сам пользуюсь KMail, поэтому не в курсе);
  • Настройки конкретного ящика.

Сделать это в виде синглтонов (последние два могут создаваться по одному на аргумент, например, имя), а оттуда уже дёргать QSettings

XMs ★★★★★
()
Ответ на: комментарий от XMs

Спасибо за полезные советы, они действительно прояснили ситуацию.

Прощай, нормальная кроссплатформенность. На тех же форточках приложения должны хранить свои настройки в реестре, а не в файле.

Тут спорный вопрос. Эта же программа, хранит настройки в реестре и не чистит их за собой после установки. Это при том, что пароль к ящику там в открытом виде, по умолчанию. Да и реестр как таковой был оправдан только в силу устройства ядра офтопа и медленных устройств хранения данных середине 90-х, ИМХО. Но это офтоп про офтопик)

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

  • Настройки приложения (пути, единицы измерения, всё, что используется приложением, но не гуёвое);
  • Настройки окон;
  • Настройки профилей, если оно у вас есть (я сам пользуюсь KMail, поэтому не в курсе);
  • Настройки конкретного ящика.

Все кроме третьего пункта имеется. Думаю, что это и будет количество групп (секций) в новом конфиге.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от next_time

Просто я о нём раньше нигде не слышал.

Вон говорят, что это просто ini-файлы на стероидах.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от next_time

Уже прочитал: Очевидный Формат дяди Тома :-)

Twissel ★★★★★
() автор топика

Мде!

В очередной раз убедился в «высоком качестве» продукции мелкомягких: 10 дней проекта я не трогал. Сегодня сел позаниматься проектом — ничего не менял бинарник собирается, но молча падает с ошибкой... капец! Опять с Studio 2015 буду перелазить на MinGW, поработал.

Twissel ★★★★★
() автор топика

Ох, и много же времени у меня сожрало SDK офтопика коих развелось как минимум 4 билда (спасибо десяточке)

Не мог понять почему при сборке с Visual C++ 2017 бинарник весело падал с кодом возврата 3.

Оказывается, что номер билда Win 10 SDK должен быть таким же, что и номер сборки библиотеки ucrtbase.dll Universal C Runtime Library в ОС, а иначе смерть ))

Короче говоря, возвращение DLL HELL во всей своей красе...

Twissel ★★★★★
() автор топика

Информация для тех, кто поставил моей репе 2 звезды на GitHub.

Пока залил туда оригинальные сорцы Trojita, т.к. было решено отказаться от идеи двух конфигов и следовательно мои предыдущие потуги стали не нужны. Они бы больше запутывали чем помогали (отдельный класс настроек AppSettings и прочее).

С недели уже точно уделю внимание этой чепухе :-)

Twissel ★★★★★
() автор топика

Eliminating global variables

Как это обычно бывает — планы были сделать все красиво и правильно, а получилось как всегда: топорно с дублированием кода, зато работает как задумано.

Избавился от глобальных переменных, с минимальными изменениями авторского кода (хоть по сути пришлось дублировать код там, где это нужно). В основной конфиг файл записывается имя профиля если главный бинарник был вызван с параметром -p

mainsettings.setValue(QLatin1String("lastUsedProfile"), profileName);

Далее в остальные 7 файлов, где использовалась скрытая глобальная переменная копипастим

QSettings mainsettings(Common::Application::mainconfigname, QSettings::IniFormat);
QString profileName = mainsettings.value(QLatin1String("lastUsedProfile")).toString();

Если бинарник был вызван без параметра --profile, устанавливаем

lastUsedProfile=main. Вот так и живём

EXL, с IPC в Trojita все нормально, это я жёстко затупил :-)

Просто у меня в офтопике не было 64-битных версий библиотеки OpenSSL 1.0, из-за этого к GMail не подключало и от балды плевалось ошибкой DBus.

На самом деле, насколько я понимаю, Qt5DBus.dll нормально эмулирует нужную функциональность.

XMs, с одним большим конфигом не стал заморачиваться под двум причинам:

  • Не стал возиться с логикой проверки существования секции настроек ящика в конфиге вроде
    bool exists = settings.childGroups().contains("mailbox");
    // ...
    
  • В случае с сабжем плохо себе представляю как загружать настройки ящика из конкретной секции. Мне показлось, что там немало работы.

И наконец, будет просьба к Qt'шникам (конечно, я и сам поищу) накидать примеров, возможно ли класс QSettings расширить/модифицировать/использовать поверх БД SQLite, нужное подчеркнуть :-)

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

Twissel ★★★★★
() автор топика
Ответ на: Eliminating global variables от Twissel

В основной конфиг файл записывается имя профиля если главный бинарник был вызван с параметром -p

А зачем вообще его записывать?


Не стал возиться с логикой проверки существования секции настроек ящика в конфиге

Не вижу проблемы:

MailboxSettings loadMailboxSettings(const QString &mailbox)
  { /* Тут уже вся кухня проверки конкретного ящика, тебе так и так придётся её где-то размещать */ }

ProfileSettings loadProfileSettings(const QString &profile)
  {
	…
	for (mailbox: mailboxNames)
		boxSettings << loadMailboxSettings(mailbox);
  }


возможно ли класс QSettings расширить/модифицировать/использовать поверх БД SQLite

Вот это точно плохая идея. KMail в своё время ругали (и продолжают ругать) за то, что вместо простой и понятной логики он теперь завязан на чудо-юдо-аконади. А ты хочешь настройки в базу данных запихнуть, чего даже подсевший на аконади KMail себе не позволяет. И, главное, чего ради?

XMs ★★★★★
()
Ответ на: комментарий от XMs

А зачем вообще его записывать?

Ну так задумано автором: если бинарник вызван с параметром -p имя_профиля, создаём профиль и/или загружаем его. Просто в оригинале имя профиля записывалось и считывалось из скрытой глобальной переменной, а в данном случае — из основного конфига.

И, главное, чего ради?

ок, постараюсь реализовать «подход один большой конфиг», не буду создавать себе дополнительные сложности.

Twissel ★★★★★
() автор топика

annulen, сейчас можно собрать Qt Webkit под Qt 5.12 и MinGW64 7.30 и что для этого нужно?

Twissel ★★★★★
() автор топика
Ответ на: комментарий от ass

:-)

Ну на онтопике не было проблем со сборкой, на офтопе я давно ничего не собирал. Так что Linux в этом плане более нормальный, кроссплатформенность обеспечивает Qt, не вижу проблемы ))

Twissel ★★★★★
() автор топика
Ответ на: комментарий от EXL

TOML это и есть QSettings .ini на стероидах.

За исключением того, что toml - это формат конфига, а QSettings .ini - формат сериализации, не предназначенный для правки руками

annulen ★★★★★
()
Ответ на: комментарий от annulen

формат сериализации, не предназначенный для правки руками

Всю жизню был уверен, что ini — это самый простой формат конфигов, своей простотой прямо-таки предназначенный для ручной правки, а тут такое

XMs ★★★★★
()
Ответ на: комментарий от annulen

QSettings .ini - формат сериализации, не предназначенный для правки руками

Где в документации об этом сказано? Откуда такая категоричность?

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

В документации не описана сериализация сложных типов и как должны экранироваться символы, так что не стоит на это завязываться.

annulen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.