逻辑和UI的分离

时间:2011-08-13 14:56:25

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

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

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

应用程序非常简单,具有主窗口和一些用户配置设置并按下按钮的对话框,程序执行(非常复杂)计算,将结果显示在UI上。

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

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

3 个答案:

答案 0 :(得分:16)

有几种方法可以解决这个问题。

  1. 您的GUI类可以从您的Logic类派生。不是典型的方法,但它取决于您的应用程序的设计方式。一个主要缺点是GUI必须与逻辑保持在同一个线程中。通常,您希望类在多个线程中运行,以至于繁重的计算不会冻结GUI。

  2. 您的GUI类可以包含指向逻辑类的指针和/或反之亦然。如果您的逻辑类存在于GUI类之前并且幸存下来,它也可能是一个方便的参考。然后你可以将引用传递给GUI类的构造函数,你就不必测试指针是否有效。

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

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

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

答案 1 :(得分:5)

有一种名为MVC(模型 - 视图 - 控制)的编程模型

对于简单的情况,只需要模型 - 视图即可。 Model表示数据,View表示UI。

模型类公开了一些接口set / get数据。 Model类通常不了解View类,但它通常可以在数据发生变化时通知View类(这可以使用Qt中的signal / slot来完成)。

View类包含一个指向Model类的指针,并使用Model类提供的接口来操作数据。

答案 2 :(得分:1)

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