【问题标题】:Separation of logic and UI逻辑和UI分离
【发布时间】:2011-08-13 14:56:24
【问题描述】:

我正在用 Qt 开发一个 GUI 应用程序。

这是我的第一个 GUI 应用程序,我不是很有经验,仍然需要与 C++ 和 Qt 框架的一些更高级的方面搏斗。

该应用程序非常简单,具有一个主窗口和一些对话框,用户可以在其中配置设置并按下按钮,然后程序执行(相当复杂的)计算,并在 UI 上的某处给出结果。

现在,我遇到了问题。我把我所有的计算数据(它是静态的并且从资源中加载)和逻辑放到一个单独的类中。我创建了这个类和 UI 类的一个实例。现在,问题是如何从 UI 类访问数据/逻辑类的成员?假设 Logic 类中有一个 QStringList,我希望某个对话框访问这个列表并将其呈现给用户,而不在内存中制作它的任何副本?

我知道这可能是一个非常基本的 C++ 问题(Qt 甚至不相关),但不是每个人都是编程向导。感谢您的任何提示或帮助!

【问题讨论】:

    标签: c++ qt separation-of-concerns


    【解决方案1】:

    有几种方法可以做到这一点,所以你的问题是有效的。

    1. 您的 GUI 类可以派生自您的逻辑类。不是典型的方法,但这取决于您的应用程序的设计方式。一个主要缺点是,如果您不想在逻辑类中涉及锁定机制,则 GUI 必须与逻辑保持在同一线程中。通常你希望两个对象在不同的​​线程中运行,这样繁重的计算就不会冻结 GUI(参见 Qt 的QObject thread affinity)。

    2. 您的 GUI 类可以保存指向您的逻辑类的指针和/或反之亦然。如果您的逻辑类在 GUI 类之前存在并且仍然存在,它也可能是方便的参考。然后您可以将引用传递给 GUI 类的构造函数,而无需测试指针是否有效。

    3. 您的 GUI 类可以通过 getter/setter 或直接访问数据成员,如果您想将它们公开或简单地将您的 GUI 类定义为 Logic 类的 friend 类。即使您使用 getter,它们也可以返回 const 引用,因此不涉及复制。像 QStringList 这样的 Qt 类也有自己的引用计数,避免复制的写时复制机制。

    4. 您的 GUI 类可以发出信号,而 Logic 类可以接收它们。请参阅 Qt 信号/槽机制。对于像“开始计算”按钮这样的事件非常好。信号有两个优点:(a)它们可以跨线程,但是如果接收器不是主循环,它会变得有点棘手; (b) 对象不必互相看到(没有指针传递),您可以将信号连接到程序中您同时看到两个对象的任何位置的槽。

    通常您将混合使用 2 和 3:使用 getter 从呈现给用户的 Logic 类中读取数据。使用信号来激发动作或操作数据(用户做出选择,逻辑类必须做出反应)。

    【讨论】:

    • 您的综合回答非常非常有帮助!现在我对这种分离有了更好的理解。谢谢!
    • 谢谢!其中有没有“最好的”?
    • 一般我会建议使用Qt信号/槽系统。然而,原因是无论如何我都会将 Qt 用于 GUI。
    【解决方案2】:

    有一种编程模型叫做MVC(模型-视图-控制)

    对于简单的情况,只需模型 - 视图就足够了。 Model代表数据,View代表UI。

    模型类公开了一些接口设置/获取数据。 Model类通常不知道View类,但通常可以在数据发生变化时通知View类(这可以通过Qt中的信号/槽来完成)。

    View 类持有指向 Model 类的指针,并使用 Model 类提供的接口来操作数据。

    【讨论】:

      【解决方案3】:

      也许我在这里遗漏了一些东西,但只需通过 setter 将您的数据类注入 UI 类,并将数据类的方法公开。您只需要传递数据类的指针即可避免任何应对开销。

      【讨论】:

        猜你喜欢
        • 2021-07-10
        • 2011-04-10
        • 2022-11-23
        • 2018-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多