Я разрабатываю средство обновления для своего приложения в Qt, в первую очередь, чтобы познакомиться с фреймворком (я понимаю, что доступно несколько готовых решений, которые здесь не актуальны). Это базовое приложение с графическим интерфейсом QMainWindow
подкласс для его главного окна и MyAppUpdater
класс для выполнения реальной логики программы.
Информация об обновлении (версия, журнал изменений, загружаемые файлы) хранится на моем сервере в виде файла XML. Первое, что должен сделать модуль обновления после настройки пользовательского интерфейса, это запросить этот сервер, получить файл XML, проанализировать его и отобразить информацию для пользователя. Вот где у меня проблема, хотя; Исходя из процедурного / C фона, я бы инициировал синхронную загрузку, установил тайм-аут, возможно, на 3 секунды, а затем посмотрел, что произойдет — если мне удастся загрузить файл правильно, я его проанализирую и продолжу, в противном случае отобразит ошибка.
Однако, увидев, как неудобно реализовывать что-то подобное в Qt, я пришел к выводу, что его сетевые классы разработаны по-другому, с другим подходом.
Я думал об инициировании асинхронной загрузки, скажем, InitVersionInfoDownload
, а затем подключение QNetworkReply's
finished
сигнал в слот называется VersionInfoDownloadComplete
или что-то в этом роде. Мне также понадобится таймер где-нибудь для реализации проверки тайм-аута — если слот не вызывается, скажем, через 3 секунды, обновление следует прервать. Однако такой подход кажется слишком сложным и в целом неадекватным ситуации; Я не могу продолжить, не извлекая этот файл с сервера или вообще ничего не делая, ожидая его загрузки, поэтому асинхронный подход в целом кажется неуместным.
Я ошибаюсь или есть лучший способ?
TL; DR: это неправильный подход в любой GUI приложение.
как неудобно что-то подобное реализовывать в Qt
Это не должно быть удобно, так как всякий раз, когда я вижу продукт доставки, который ведет себя таким образом, у меня возникает желание строго поговорить с разработчиками. Блокировка GUI — это кошмар юзабилити. Вы никогда не хотите кодировать таким образом.
Исходя из процедурного / C фона, я бы начал синхронную загрузку, установил тайм-аут, может быть, 3 секунды, а затем посмотрим, что произойдет
Если вы пишете какой-либо код управления машиной или интерфейсом в C, вы, вероятно, не хотите, чтобы он был синхронным или. Вы бы настроили конечный автомат и обрабатывали все асинхронно. При кодировании встроенных приложений на Си конечные автоматы делают сложные вещи совершенно тривиальными. Есть несколько решений, QP / C будет первым примером класса.
думал о том, чтобы инициировать асинхронную загрузку, скажем, в InitVersionInfoDownload, а затем подключить законченный сигнал QNetworkReply к слоту с именем VersionInfoDownloadComplete, или что-то в этом роде. Мне также понадобится таймер где-нибудь для реализации проверки тайм-аута — если слот не вызывается, скажем, через 3 секунды, обновление следует прервать. Тем не менее, этот подход кажется слишком сложным
Это тривиально. Вы не можете обсуждать такие вещи, не показывая свой код: возможно, вы реализовали его каким-то ужасно многословным образом. Когда все сделано правильно, он должен выглядеть стройным и сладким. Для вдохновения см. этот ответ.
Я не могу продолжить, не получив этот файл с сервера, или действительно что-то сделать, ожидая его загрузки
Это явно ложно. Ваш пользователь может пожелать отменить обновление и выйти из приложения, либо изменить его окно, либо уменьшить / развернуть его, либо проверить существующую версию, либо ОС может потребовать перерисовки окна, или …
Помните: ваш пользователь и окружающая среда находятся под контролем. Приложение, не отвечающее по своему дизайну, не только ужасно воспринимается пользователем, но и усложняет понимание и тестирование вашего кода. Псевдосинхронные спагетти быстро выходят из-под контроля. С асинхронным дизайном тривиально использовать сигнальный шпион или другие продукты для анализа того, что делает приложение, где оно застряло и т. Д.
Других решений пока нет …