我正在为Qt中的应用程序开发更新程序,主要是为了了解框架(我意识到有多个现成的解决方案,这里没有相关性)。它是一个基本的GUI应用程序,它的主窗口使用QMainWindow
子类,执行实际的程序逻辑使用MyAppUpdater
类。
更新信息(版本,更改日志,要下载的文件)作为XML文件存储在我的服务器上。更新程序在设置UI后应该做的第一件事是查询服务器,获取XML文件,解析它并向用户显示信息。这是我遇到问题的地方;来自程序/ C背景,我启动同步下载,设置超时可能是3秒,然后看看会发生什么 - 如果我设法正确下载文件,我将解析并继续,否则显示错误。
然而,看到在Qt中实现这样的不方便,我开始相信它的网络类是以不同的方式设计的,并且考虑了不同的方法。
我正考虑在InitVersionInfoDownload
中启动异步下载,然后将QNetworkReply's
finished
信号连接到名为VersionInfoDownloadComplete
的广告位,或者沿着这些行添加某些内容。我还需要一个计时器来实现超时检查 - 如果在3秒后没有调用插槽,则应该中止更新。但是,这种做法似乎过于复杂,而且总体上不适合这种情况;如果没有从服务器检索这个文件,或者在等待下载它时确实做了什么,我就无法继续,所以异步方法通常是不合适的。
我错了,还是有更好的方法?
答案 0 :(得分:4)
TL; DR:这是任何 GUI应用程序中的错误方法。
在Qt中实现这样的不方便
这并不意味着方便,因为每当我看到运送产品的行为方式时,我都渴望与开发人员进行严格的交谈。阻止GUI是一个可用性的噩梦。你永远不想以这种方式编码。
来自程序/ C背景,我发起同步下载,设置超时可能是3秒,然后看看会发生什么
如果您在C中编写任何类型的机器或接口控制代码,您可能不希望它同步 。您将设置状态机并异步处理所有内容。在对嵌入式C应用程序进行编码时,状态机使得困难事情变得微不足道。有几种解决方案,QP/C将是一流的例子。
正考虑在InitVersionInfoDownload中启动异步下载,然后将QNetworkReply完成的信号连接到名为VersionInfoDownloadComplete的插槽,或者沿着这些线路连接。我还需要一个定时器来实现超时检查 - 如果在3秒之后没有调用插槽,则应该中止更新。但是,这种方法似乎过于复杂了
这是微不足道的。如果不显示您的代码,您就无法讨论这些事情:也许您已经以一种非常冗长的方式实现了它。如果做得恰当,它应该看起来很瘦,很甜。如需灵感,请参阅this answer。
如果没有从服务器检索此文件,或者在等待下载文件时确实做了什么,我无法继续
这显然是假的。您的用户可能希望取消更新并退出应用程序,或调整其窗口大小,或最小化/最大化它,或检查现有版本,或者操作系统可能需要窗口重绘,或者......
请记住:您的用户和环境处于控制之中。设计不响应的应用程序不仅会带来糟糕的用户体验,还会使您的代码难以理解和测试。伪同步意大利面很快失控。使用异步设计,使用信号间谍或其他产品来内省应用程序正在执行的操作,卡在哪里等等都是微不足道的。