问题 基于Qt的UI是否足够可靠,可用于医疗设备? [关闭]


我在一家小公司工作,开发具有丰富UI的复杂医疗设备。我们目前处于设计的早期阶段。该应用程序针对Windows(仅限桌面),最好只能用C ++编写。

经过一些研究后,我们倾向于选择Qt来开发UI。它似乎满足了我们所有的需求,即可以开发具有现代外观和高响应性的UI,开发速度相当快(熟悉后),内存使用在某种程度上是合理的,免费用于商业用途(对我们来说是奖励)。

我的问题是:它对于医疗设备是否足够可靠?我们绝对不能接受考试中的任何崩溃。我知道首先它当然取决于我们编写的代码质量,但我仍然想知道是否有人遇到任何特别难以解决的与崩溃相关的神秘问题。特别是当使用作为脚本语言的QML时,它自然会导致难以预测和解释的错误。

在生产中遇到这样一个问题的成本对我们来说非常高,所以在我们选择任何特定的包之前,我们非常需要做出正确的决定。如果您知道在我们的特定环境中可能出现的任何其他与Qt相关的问题(我承认无法进行非常广泛的包测试),我也非常感谢您提及它。


5011
2017-07-31 08:32


起源

所以你打算根据陌生人的建议打赌农场,他们提供这些建议的资格完全不为你所知?听取我的建议,得到更好的建议。 - High Performance Mark
当qt撞毁呼吸机并且病人死亡时,诺基亚会不会付钱吗?也许你可以找到他们的一些交易。例如,如果成本超过10万欧元,他们将支付。 - Johannes Schaub - litb
我想像Qt这样的每个高度复杂的UI工具包都有它的缺陷。你必须通过执行足够的测试来了解并避免它们。如果您开发自己的UI,它将没有什么不同。 - scai
我现在肯定会远离QML。这仍然是一项相对较新的技术,它可能不如图书馆的其他部分稳定。 - this.lau_
@HighPerformanceMark我并不是真的想要依赖陌生人的建议,只是想从更有经验的人那里学到一些东西。这个网站有良好的声誉,所以我希望能够给出有价值答案的人做到这一点,我会考虑他们的意见。特别是如果他们有良好的声誉 - 就像你的。无论如何,我可以看到你的观点,我会认真对待你的建议。谢谢! - user1526557


答案:


在我看来,如果你遵循他们的编码风格,Qt足够稳定。我还会购买Digia的支持并使用该库的稳定版本。

事情归结为:

  • 评估使用Qt(或任何其他GUI库)引入的风险
  • 针对这些风险采取防御措施(引入涵盖风险的新要求和测试,例如将GUI作为通过TCP或其他方式与核心通信的单独进程运行)
  • 评估应用程序崩溃的风险,并记录该方案发生时要遵循的过程。

根据我对医疗设备认证的经验,设备的大声崩溃优于静音和错误的操作设备。 如有疑问,请询问正在关注您的案件的认证机构。

另外,看看标准(例如60601-1-4或现在使用的任何标准)。

Qt在医疗应用中的用法: http://qt.nokia.com/qt-in-use/qt-in-medical/


4
2017-07-31 11:50



相关标准是IEC 62304,用于嵌入医疗设备的软件(60601用于“医疗电气设备”,与软件没有直接关系)。 - Julien-L


我会认为高可靠性工程的基本原则是充分的。有了这些,你可以使用Qt。现在,Ambroz Bizjak提到了一些“麻烦”的情景。当你遵循基本规则时,它们是无关紧要的。

那么,这些规则是什么?他们不是很难。确定可能失败的位,并在故障不严重时执行这些操作。例如,Ambroz对窗口删除有一个很好的观点。不要在考试中这样做。将对象转储到延迟删除队列中,并确保它们不会干扰操作(即对象必须具有被动状态。例如,对于小部件,包括不可见)。同样,在开始检查之前,创建您可能需要的所有对象(包括所有可能的对话框窗口)。

你可以很好地总结一下这个

  1. 可能失败的准备工作
  2. 事情可能不会失败
  3. 可能失败的清理

由于已经提到的原因,我会避免使用QML。上面的计划突出了它为何如此成问题。您无法将所有可疑的QML步骤移至准备阶段。


3
2017-07-31 11:37



我的观点也是,不是吗 比较喜欢 如果你可以删除那个窗口,和 相信 正确完成工作的框架?在编写可靠的系统时,我当然会。 - Ambroz Bizjak
我也更喜欢系统 new 永远不会扔。但作为一名工程师,我工作的核心任务之一就是应对我周围世界不可避免的不完美。 - MSalters
这根本不一样。我暴露的设计问题实际上有解决方案,可能有更好的替代Qt,但每台计算机都有有限的内存。而内存耗尽则不然 那 难以避免 - 确保没有内存泄漏,并为您加载的内容添加一些安全上限。例如。如果这是一个图像查看器,添加一个你从不打开超过N个图像的限制,并且没有一个图像大于XxY。 - Ambroz Bizjak
@AmbrozBizjak:当然,我很想相信这个框架是100%无错误的...但是回到现实世界中,你必须接受没有什么是完全错误,缺陷和副作用免费的。 - gbjbaanb


我假设您没有开发安全关键设备,因为您运行Windows并且Windows许可协议有一些关于此的说法。所以你的问题确实是, “我们正在制造一种必须尽可能稳定的消费产品,否则我们会看起来非常非常糟糕”

就个人而言,我可以建议使用C#,因为它在Windows下具有出色的工具,并且开发起来更加容易和安全(垃圾收集器是您的稳定性的朋友,如果不是性能),并且单元测试稍微更方便。对任何性能关键部分使用C ++或C ++ / CLR,但没有理由使用这种复杂且具有潜在危险的语言来构建GUI。


2
2017-07-31 09:31



以安全的语言编写(例如意外的异常而非完全崩溃)并不会使您的程序更可靠。让它更可靠的是思考它(证明它的事实)并测试它。在某些语言中,这些东西比其他语言更容易。实际上,C似乎被广泛用于安全关键系统。这个问题可能相关: stackoverflow.com/questions/243387/... - Ambroz Bizjak
@AmbrozBizjak:它通过生成异常而不是允许由缓冲区溢出等引起的损坏来删除整个类的细微故障。它提供了大量检查和断言不变量的方法,并且有许多工具可用于帮助推断您的软件。但是,我的观点是假设OP是 不 写一个安全关键系统。安全关键系统往往需要实时性能保证,无论是窗口,CLR还是C#都无法提供;在这种情况下,C是一个不错的选择。 - Rook
@ user1526557:如果您正在编写一个安全关键系统,如果在运行时出现问题可能导致人身伤亡,那么对GUI技术的讨论就非常不合适且无关紧要。 现在停下来寻求一些专业建议! 我认为Stack Overflow不一定能帮助您通过FDA认证。但至于WPF;是的,它正在走出去。在等待合适的替代品(例如WinRT)时,Windows Forms是一种可行的替代方案。 - Rook
@Rook:你错了缓冲区溢出问题。在安全关键代码中,缓冲区溢出的后果是不可接受的。因此,您在开发过程中确保它们不会发生。结果,与他们之后发生的事情完全无关。宇宙射线变得更加重要,因为它们 做 发生。 - MSalters
是的,所以我原来的改写, “我们正在制造一种必须尽可能稳定的消费产品,否则我们会看起来非常非常糟糕”,准确。请不要混淆这个问题,说它是安全关键的!我将重复我原来的C#建议。它得到操作系统供应商的支持,是一个拥有出色工具的成熟平台。对于仅限Windows的应用程序,我肯定会在Qt和C ++上选择它。 - Rook


从我对Qt的经验来看,当可靠性很重要时,这是一个糟糕的选择。例如,许多崩溃是由看似有效的代码引起的,但是在某些特定的上下文中做了某些事情,Qt的某些部分没有预料到。在这里,我列出了Qt在编写正确代码时遇到的一些问题:

  • 删除QObjects(读取:任何东西)是一个非常痛苦的过程。如果你从这个对象发出的信号中删除它(读取:一半的时间),你的程序可能会崩溃,因为发出信号的代码不会在你发出处理程序返回信号后检查对象是否仍然存在。继续使用它。

  • 如果仔细观察,建议的解决方法是使用QObject :: deleteLater(),这将使事件循环删除对象 有时候,它是安全的。虽然这看起来似乎可以接受,但考虑到那段时间内的对象 仍然存在并且可以发出信号。这会引入不必要的中间状态,您必须处理这些状态  介绍错误;很可能在非常特殊的情况下很少发生(读:不是在你测试的时候)。无论如何, 这一页 讨论了QObject删除的一些问题。

  • Qt中的其他类具有类似的删除相关问题。例如,如果在其mousePressEvent处理程序中从其场景中删除项目(而不是删除它),QGraphicsScene :: removeItem()可能会导致崩溃。这似乎没有在任何地方记录。

  • Qt课程充满了 便利功能 与核心功能组合在一起,很难弄清楚课程的实际运作方式以及如何正确使用它。例如,除了stateChanged()信号旁边的QProcess,它是唯一需要的信号,它有像error(),finished()和started()这样的信号,它们的语义和正确的处理并不完全清楚。

  • 许多抽象接口设计糟糕且定义不明确。例如,类QIODevice用于 阅读和写作 和 阻塞和异步I / O.。一个类可以自由选择要实现的子集。这违反了抽象接口的整个概念,即实现接口的任何东西都以定义和一致的方式工作。

  • 没有 真的很好,很均匀 处理事件的方式。有两种 事件 在Qt: QEvents,通过重新实现虚函数来安装回调,以及 信号为什么? 无论如何,这两种事件最终只是调用函数(直接在这里忘记排队信号)。这意味着各种模块只能通过调用彼此的功能进行通信。如已经看到的那样,这是有问题的,因为当模块调用另一个模块时,其他模块可能真的已经完成了 什么并且可能很难在每个回调站点考虑所有可能的场景(正如我们所见,Qt没有,而是崩溃)。

    通过向事件循环添加功能可以完全解决此问题,这允许跨模块更容易地进行通信和同步。我在描述这个设计 这个问题

总而言之,当你瞄准最大可靠性时 不要 您基于程序的框架中的此类设计问题 不要 几乎每一步都要解决它的问题。即使你正确地解决了你能想到的所有问题, 你怎么知道没有更多?我想你应该尝试在Qt中编写一些完全正确的代码(也就是说,阅读所有文档,并且 思考每一步 你正在做什么以及框架将如何反应)。过了一段时间,问问自己:你呢? 相信 框架,还是你觉得它试图欺骗你?


1
2017-07-31 09:50



您链接的对象删除页面包含有关线程安全的信息,该信息仅适用于4.0之前的Qt版本(7年前发布)。 Qt当然不是没有错误,但总的来说我发现它比你在这里描述的更可靠(除了QML,我最后一次使用它完全充满了内存泄漏和其他问题)。 - Dan Milburn
@AmbrozBizjak感谢您抽出宝贵时间回答并提供所提供的信息。你能否描述一下你用Qt开发的哪种应用程序?您可以考虑哪些C ++ UI工具包真的可靠? - user1526557
@DanMilburn肯定,一些错误已得到修复,但我指出的一般问题仍然存在。我认为removeItem()崩溃发生在Qt 4.7中。 - Ambroz Bizjak
@ user1526557对于我用过的应用程序来说它足够可靠。我没有太多其他工具包的经验,但我已经使用Qt从QML手机应用程序到非常大的桌面GUI应用程序,它已经足够可靠了。 - Dan Milburn
@ user1526557 快速 和 安全关键 不要混在一起好。实际上,它们根本不混合。 - Ambroz Bizjak