【问题标题】:How to write a GUI for a large cross-platform C++ project?如何为大型跨平台 C++ 项目编写 GUI?
【发布时间】:2010-02-03 12:05:59
【问题描述】:

我有一个大型跨平台(Linux 和 Windows)C++ 项目,我想为其创建一个 GUI。

对于此类项目的 GUI 基本原则,我有几个非常普遍的问题:

  1. 是否应该将 GUI 与应用程序的逻辑分开?
  2. 如果分开,逻辑和GUI应该如何通信? TCP/IP 套接字是一个不错的选择吗?还有哪些可能?
  3. 让 GUI 使用不同于 C++ 的语言是个好主意吗?如果是 - 哪种语言?
  4. 拥有基于浏览器的 GUI 是个好主意吗?
  5. 尽管项目的核心逻辑是跨平台的,但我可以决定 GUI 将仅基于 Windows(.NET?),它将通过 Socket 或类似方法与相关 Win/Linux 机器上的逻辑通信.这样做是个好主意吗?

【问题讨论】:

  • 你研究过 Qt 吗? qt.nokia.com/products
  • 是的,我研究过 Qt。这是选项之一。
  • 还是单声道? mono-project.com/Main_Page
  • 尽管有些人无疑会尝试回答您的问题,但您的每一个问题的真正回答都是“视情况而定”。这些决策是应用程序架构的一部分,应该由您或相关架构师做出。您提供的是豪宅的钥匙孔视图,并要求提供结构施工建议,如果没有全貌,建议无疑是主观和不准确的。我建议回到您的应用设计并寻找解决您遇到的痛点的方法,而不是从解决方案中倒退。
  • @Igor,对于每个问题,您需要问自己/赞助商/关键利益相关者“这对于应用程序的实施和操作是否必要?”这是第一个取决于。请记住,通常还需要考虑未来,即单一应用程序现在可能适合您的要求,但将来不适合。这里没有足够的信息来做出决定,如果有足够的信息,那么您需要比问答网站提供的更多帮助。要么阅读有关软件架构的所有内容,要么聘请架构师。就目前而言,“视情况而定”是每个问题的全部答案。

标签: c++ user-interface cross-platform


【解决方案1】:
  1. 是否应该将 GUI 与应用程序的逻辑分开?

    是的,当然……

  2. 如果分开,逻辑和GUI应该如何通信? TCP/IP 套接字是一个不错的选择吗?还有哪些可能?

    ...但不是那么。套接字将是多余的(例外:请参阅问题 5)。通常,您将 GUI 和后端部分中的类分开。 GUI 类然后调用后端的方法。

  3. 使用不同于 C++ 的语言使用 GUI 是否是个好主意?如果是 - 哪种语言?

    如果是这样,您将不得不整合这两种语言,因此我建议您使用相同的语言编写所有内容。但要回答您的问题,您可以为后端创建 Python 绑定并用 Python(使用 PyGTK、PyQT 或 wxWidgets)编写 GUI。

  4. 拥有基于浏览器的 GUI 是个好主意吗?

    这取决于您希望如何部署应用程序。如果它应该安装在每台客户端计算机上,那么 Web 界面就没有意义了。如果您想集中托管它,那么您可能会选择 Web 界面。

  5. 尽管项目的核心逻辑是跨平台的,但我可以决定 GUI 将仅基于 Windows(.NET?),它将通过 Socket 或类似方法与相关 Win/Linux 机器上的逻辑通信.这样做是个好主意吗?

    我认为这才有意义只有在后端必须是某种安全的(即不得安装在用户的计算机上)或者如果您有问题 4 中类似瘦客户端的方法. 编写跨平台的 GUI 比编写跨平台的后端要容易得多(在我看来),所以你应该跨平台做这两个部分。顺便说一句,基于 .NET 的 GUI 并非仅限 Windows - 例如,Mono 已经支持 Windows 窗体的一个很好的子集(但遗憾的是,不支持 WPF)。

编辑:

关于您的 Mono 问题:Mono 基本上是稳定的,但并非所有内容都已实现。可以肯定的是,您可以运行The Mono Migration Analyzer (MoMA) 来确定在 Mono 中是否有问题。但我认为so many companies 在生产环境中成功使用 Mono 的事实意味着您至少应该考虑使用 Mono!

【讨论】:

  • 我喜欢你的回答,但我完全不同意:“编写跨平台 GUI 比编写跨平台后端容易得多”。我绝对说相反。如果您编写 vanilla C++(好的,乐观的),则很少有可移植性问题。但是,使丰富的现代 GUI 保持一致并满足可移植性以及本机操作系统用户体验可能是一个真正的挑战 - 有时它在原则上是矛盾的。
  • 当他这么说的时候,我想他是在假设一个跨平台的 GUI 库(例如 Qt)会被使用。由于库开发人员已经处理了特定于平台的代码部分,因此创建跨平台 GUI 有时会比跨平台后端(可能需要进行一些特定于平台的函数调用)更容易。
  • 关于 .NET - 我听说有一种方法可以将任何 .NET GUI 导出到浏览器。你熟悉吗?它只是 .NET 技术的原生部分,还是一些外部工具?
  • @Igor Oks:WPF(.net 3.0 中引入的新“Win Forms”技术)的范围非常小,可以在桌面或 Broswer 上运行,甚至在你ve 专门设计您的 UI,因此如果它在浏览器中运行(谷歌 XBAP 获取更多信息)将是有意义的,因此您最终会得到一个看起来像浏览器 UI 的桌面 UI。对于“任何 .NET GUI”来说,这肯定不是真的,对不起,伙计。
  • @RED SOFT ADAIR:我的意思是 bta 已经说过了。鉴于已有稳定的跨平台 GUI 库,如 Qt、wxWidgets 和 GTK+,移植用户界面非常容易,因为代码通常是相同的(或与 Glade 一样的 XML 文件)。在我的回答中,我将其与编写与操作系统无关的后端进行了比较,在后端你必须自己编写所有可移植代码。
【解决方案2】:

是否应该将 GUI 与应用程序的逻辑分开?

应该,因为 UI 小部件只是对象的类型,而 OO 的规则之一是每个 对象应该被信任它可以履行的责任。一个对话框不太了解 例如序列化。

如果分开,逻辑和GUI应该如何通信?是 TCP/IP 套接字是一个不错的选择吗?什么是 其他可能性?

这取决于您需要多少分离。我使用异步消息进行通信,然后我可以使用 不同的传输层没有很多变化。 TCP/IP 将允许您在与内核不同的机器上使用 GUI,但它的开销高于 例如传递窗口消息。

将 GUI 放在一个 与 C++ 不同的语言?如是 - 哪种语言?

理想情况下,您应该尽可能少使用语言,除非您确实需要 某种语言。 GUI 更像是一个库问题而不是语言问题,所以如果你能找到一个非常好的 C++ UI 库(提示:Qt),您应该用 C++ 编写所有程序。

有一个好主意吗? 基于浏览器的 GUI?

可能是,但您应该考虑需求而不是想法。您的客户是否想与之互动 你的程序从浏览器?他们能负担得起额外的成本和开发时间吗?你有诀窍吗?

尽管项目的核心逻辑 是跨平台的,我可以决定 GUI 将仅基于 Windows (.NET?),它将与 相关 Win/Linux 上的逻辑 通过Socket或类似的机器 方法。这样做是个好主意吗?

这可能是个好主意,但请参阅#3 的答案。还要考虑您将要在客户端-服务器程序上工作,这比独立程序要复杂得多。 最后,您需要检查 .NET 依赖项相对于使用 C++ UI 库的优缺点:.NET 带给您的东西是 wxWdigets、Qt、gtkmm 等无法获得的。

【讨论】:

    【解决方案3】:

    (1) 通常是的,这样可以分别维护业务逻辑和用户界面。它还使您以后可以拥有例如既是基于浏览器的 SaaS 用户界面,也是桌面式的本地无网络操作模式,仍然共享整个应用程序逻辑代码。

    (2) 不使用 TCP/IP 套接字。通常,应用程序和 GUI 将使用事件和/或消息传递进行通信。例如,当应用程序想要通知 GUI 某事发生时,它会创建一个合成事件,然后将其推送到 GUI 的事件队列中。如果应用程序也是基于事件的,则 GUI 可以通过发布事件与其进行通信。对于非阻塞的快速操作,GUI 可以直接调用应用程序逻辑代码,但必须保证调用快速返回。对于较慢的操作,无论如何您都需要一个单独的线程来处理它们。该线程可以是处理应用程序端事件的线程,或者您可以在需要时将其作为工作线程生成。

    我们公司的产品在 Eclipse IDE 之上有一个用户界面,但部分应用程序逻辑是用 C++ 编写的。这两部分通过 CORBA 进行通信,即基本上是异步事件机制。我们对这个解决方案很满意。

    在较小的规模上,GUI 应用程序通常使用模型-视图-控制器 (MVC) 等抽象来分离 UI 和应用程序逻辑。

    (3) 集成用两个不同组件编写的组件总是很麻烦。我认为只有在您有明显的平台优势时才应该这样做。例如。我们受益于 Eclipse IDE 组件,而应用程序则受益于 C++ 的原始速度。

    (4) 基于浏览器的 GUI 很棒,但是与业务逻辑的集成会受到延迟的影响,如果您实际上拥有桌面风格的应用程序,那么 Web 服务器的无状态模式会使架构变得很麻烦。基于浏览器的 GUI 非常适合软件即服务应用程序,因为它们不需要用户安装,并且可以由产品开发人员随意升级,但如果您不打算将产品作为软件即服务产品(例如 Salesforce)。

    (5) 如果你的应用逻辑是跨平台的,我会尽量让 UI 也跨平台。否则,对于那些只支持应用程序逻辑的平台,您可能需要安装两个操作系统,一个运行 UI,一个运行应用程序逻辑。至少有很好的跨平台用户界面框架

    • AJAX/基于浏览器的用户界面
    • 奇趣科技/诺基亚 Qt
    • Eclipse (SWT)
    • Java Swing(嗯...)

    【讨论】:

    • 关于事件和/或消息传递:它是此类项目的常见解决方案,还是比 TCP/IP 套接字使用得更少?有什么好处?
    • 关于跨平台 GUI,您没有提到 .NET(通过 MONO)。为什么不是一个选项?
    • @Igor 我没有得到关于 MONO 的很好的反馈 Windows .NET 实际兼容性,但也许它可以工作
    【解决方案4】:

    最好使用 python 作为你的基本 gui 语言和 QT 作为 gui 平台。 如果您将 gui 和基本程序拆分为不同的进程,那么您可以使用这种机制进行通信:

    1. 来自 Qt 的信号和槽
    2. python 中的子进程模块
    3. 本地套接字。
    4. 使用文件[将配置写入文件并通知其他进程刷新]

    但最好创建一个进程并直接从 python 调用您的基础语言并与本机语言的数据结构进行通信。你的猫为此目的使用 swig。但是因为你不能从 C++ 中调用 python 函数,所以你可以在 python 中使用池来对共享数据进行一些更改,并根据这些更改做一些事情。我经历了两种方式。当我使用 python 进行 GUI 和管理时,它可以非常节省时间。

    【讨论】:

    • 你说用python+QT比较好。比什么更好?
    【解决方案5】:

    1. GUI 是否应该与应用程序的逻辑分离?

    是的。但是,请参阅答案 #2

    2.如果分开,逻辑和GUI应该如何通信? TCP/IP 套接字是一个不错的选择吗?还有哪些可能?

    我相信这是选择 GUI 框架、MFC、.NET、wxWidgets、Qt 等的最佳答案。 您选择的框架将尽可能轻松地为您处理分离和通信。

    不要试图重新发明轮子。框架设计者在他们的实现中投入了更多的思考和测试,这是您负担得起的。

    请注意,问题 #1 表明您要询问的是在单个应用程序中分离逻辑。但是,后面的问题表明您可能正在考虑两个独立的应用程序,甚至可能在不同的机器上运行。

    我认为将 GUI 放在完全独立的应用程序中总是会导致速度缓慢且不灵活。但是,如果您不关心速度和灵活性,尤其是如果您已经使用简单的控制台类型界面运行核心应用程序,那么这可能是最好的选择。

    3.让 GUI 使用不同于 C++ 的语言是个好主意吗?如果是 - 哪种语言?

    没有。

    如果你是一个单人编程团队,那么你会在试图掌握两种语言的过程中过于分散自己。如果您是一个多人团队,为什么要通过设置两种不同的文化来加剧沟通问题?

    4.拥有一个基于浏览器的 GUI 是个好主意吗?

    如果你能避免它,就不会。如果您需要基于浏览器的 GUI,那么您就会知道。如果您不需要,请保持简单并跳过它。

    5.尽管项目的核心逻辑是跨平台的,但我可以决定 GUI 将仅基于 Windows(.NET?),它将通过 Socket 或类似方法与相关 Win/Linux 机器上的逻辑通信。这样做是个好主意吗?

    与#4 相同的答案

    【讨论】:

      【解决方案6】:

      一些用户已经对你的问题给出了很好的答案,这就是为什么我想给你一些我如何处理我的项目的提示。

      问:我的应用程序应该在哪个操作系统上运行?

      Windows 和 Linux! -> 我会使用 C++ 或 Java

      问:运行时速度重要吗?

      是的! (计算、绘图、访问系统资源……) -> 鉴于速度 C++ 通常更快(并非总是)

      问:需要配置文件吗?

      答:是的!我必须设置一些用户和系统特定的值。 -> 可以将配置保存到注册表中,但由于我们也想在 linux 上使用我们的应用程序,所以我们使用 xml(对于 C++ 来说,rapidxml 将是一个很好的解决方案)

      问:需要数据库吗?

      答:是的,我有一些信息/计算需要保存(本地/全局)。 -> 本地:我会使用 sqlite -> 如果您只需要保存相对较少的信息,请考虑使用更快的方式来存储这些信息(xml?!)

      问:我应该如何构建我的应用程序?

      答:始终将您的 GUI 与“逻辑”部分分开 -> 让您以后更容易更改代码,并且您也可以将代码用于其他项目。 + 已经提到的原因。

      问:我应该如何构建我的 GUI?

      答:考虑一下您的应用程序应该用于什么以及用户应该能够做什么。啊,请不要创建太深的层次结构,这意味着用户不必打开 10 个窗口即可打开他们想要的窗口。您的代码也是如此,拥有太多创建新对象的对象不是一个明智的决定。

      object->object->object->object->object->object->object->object
      

      问:我的应用程序是否必须与服务器应用程序通信?

      答:是吗?你必须使用套接字!但请记住,通过套接字进行的通信不是非常快速和安全,因此如果非必要,请不要使用它们。

      问:我不知道如何开始(我们是一群开发者)

      A:当开始一个新项目时,我会考虑所有这些要点(可能还有更多) + 为了查看我需要哪些类和方法,我首先创建一个 UML 图,这将帮助我了解在哪里我应该开始,该图还将帮助我跟踪我的类和方法以及它们如何相互关联。 UML 图还将帮助您的伙伴或客户了解您的应用程序的结构。

      对于更大的项目,我会使用 C++ 和 wxWidgits 或者 Qt。 (只是我的观点)

      Rgds 莱恩

      【讨论】:

        【解决方案7】:

        如果您想要一个免费且编写良好的跨平台 GUI 解决方案示例,我建议您查看 wxWidgets (1)。我希望这会有所帮助

        【讨论】:

        • wxWidgets 域名现已出售。
        【解决方案8】:

        我的回答非常笼统,因为您没有告诉任何有关您的应用程序的信息。

        是否应该将 GUI 与应用程序的逻辑分开?

        在代码中,绝对是。在单独的进程中运行(可能在单独的机器上)也可能是一个好主意,但这实际上取决于您的要求。

        完全分开的原因:

        • 在 GUI 未运行时将应用程序作为守护程序或系统服务(在后台)运行
        • 通过网络远程控制应用程序
        • 可以使用不同的编程语言(例如 iPhone?)实现多个独立的 GUI 实现
        • 支持无 GUI 的自动控制(脚本)
        • 如果一开始不这样做,以后再实施分离几乎是不可能的

        为什么不分开的原因:

        • 需要对所有 I/O 进行序列化,这使得实施更加困难
        • 如果传输大量数据,性能会略有下降(这实际上不会以任何方式影响您的典型 GUI 应用程序)

        如果分开,逻辑和GUI应该如何通信? TCP/IP 套接字是一个不错的选择吗?还有哪些可能?

        HTTP 是一种流行的选择,它避免了防火墙等的大多数问题。在 C/C++ 中,您可以将 libcurl 用于 http/https 请求和 Boost.CGI(尚未被 Boost 接受)或服务器端的其他 CGI 库之一。

        IPC 的其他选项包括共享内存 (Boost.Interprocess)、UNIX 套接字和其他网络协议。但是,除非传输大量数据,否则我不会推荐这些。

        使用不同于 C++ 的语言使用 GUI 是否是个好主意?如果是 - 哪种语言?

        我认为这没有什么好处。尽管如此,分离 GUI 允许使用不同的语言编写它——甚至可能是它的多个实现。

        拥有基于浏览器的 GUI 是个好主意吗?

        当然。 如果你需要的东西可以用 HTML5 和 JavaScript 来完成,甚至不要考虑传统的 GUI,而是把它变成一个 webapp。

        好处是:

        • 完全跨平台
        • 没有在用户机器上安装软件
        • 所有客户端始终使用最新版本的 GUI
        • Web GUI 框架实际上比传统 GUI 框架更易于使用
        • 无需将 GUI 分离到单独的进程中
        • 仍然可以从脚本中使用(例如,在 shell 脚本中使用 curl 程序)

        另一方面,您的性能会略有下降,但对典型的 GUI 应用程序的影响仍然不够重要。

        尽管项目的核心逻辑是跨平台的,但我可以决定 GUI 将仅基于 Windows(.NET?),它将通过 Socket 或类似方法与相关 Win/Linux 机器上的逻辑通信.这样做是个好主意吗?

        跨平台 GUI 库的 API 有点可怕。 Qt 现在在看原生方面做得很好,它的 API 也相当不错,尽管它对你的应用程序有重大影响。尝试将 Qt 的任何使用严格限制在 GUI 内。真正的原生跨平台 GUI 的另一个选择是 wxWidgets,它可以更好地与其他 C++ 代码集成,但有一个非常讨厌且容易出错的 API。

        对于 Web UI,您绝对应该考虑 Wt,它是一个高级 C++ AJAX 框架,其界面类似于 Qt,但使用现代 C++ 实践而不是像 Qt 那样接管您的应用程序。

        【讨论】:

          【解决方案9】:

          我同意评论员所说的“信息不足”,但根据您的需要,您应该对网络浏览器界面给予很多考虑。

          如果实时流数据和即时满足的交互性不重要,那么 Web 界面可以相当简单,无需 AJAX,只需简单的基于表单的 CGI 和动态生成的 HTML。请记住,随着 Windows、Linux、Mac 或其他系统的任何变化,浏览器正在使用其他人的钱为您更新。

          您的用户已经觉得这很熟悉。您可以找到程序员来完成这项工作。 如果需要,几乎所有主要语言都已经存在库,可以将 Web 服务器本地嵌入到应用程序中。或者您可以运行某种集中式服务器。

          浏览器已经有很好的方法来分离内容、输入(表单)、样式和增强功能,这样很容易在未来找到可以开发或更改相关组件的人。

          有些人可能会说这对应用程序的独立版本不利,但我说这对独立版本来说是好的,只要您添加一些安全性(运行嵌入式网络服务器,其中只有来自本地计算机的请求才会得到响应)。通过从应用程序启动浏览器或告诉用户在启动消息中去哪里(URL http://localhost:7654 或其他任何内容,而不是他们的永恒目的地:-)),用户的生活可以变得更轻松。

          【讨论】:

            【解决方案10】:
            1. 是否应该将 GUI 与应用程序的逻辑分开?

            是的。

            1. 如果分开,逻辑和GUI应该如何通信?是 TCP/IP 套接字是一个不错的选择吗?什么是 其他可能性?

            TCP/IP 走得太远了。使用 OOP 或任何其他结构化编程方法分离应用程序逻辑和 GUI。

            1. 让 GUI 使用不同于 C++?如果是 - 哪种语言?

            就跨平台应用程序而言,C++ 已经足够好了。其他选项是 Java 和 .NET,在这种情况下,大多数跨平台的东西都得到了处理……尽管没有 C++ 提供的控制程度。

            1. 拥有基于浏览器的 GUI 是个好主意吗?

            只要您的应用在用户交互过程中不需要太精细的控制,这是最好的主意。

            1. 虽然项目的核心逻辑是跨平台的,但我可以决定 GUI 将是唯一的 基于 Windows 的(.NET?),它将 与逻辑上的通信 相关Win/Linux机器通过 套接字或类似方法。是不是一个好 有想法吗?

            恕我直言,使用套接字增加的复杂性是不值得的。

            SciTE 是一个很好的例子,一个简单的跨平台应用程序。对于 Windows 程序员来说,源代码应该很容易理解。我建议您下载源代码并查看两个平台(Windows 和 GTK)如何处理相同的代码库。

            【讨论】:

              【解决方案11】:

              你有很多好的答案,但我还是会自己写

              是否应该将 GUI 与应用程序的逻辑分开?

              我认为这是最好的。因此,在进行修改时,您可以更轻松地处理它。此外,使用多平台的 GUI 框架,并绑定其他语言,例如 GTK+ 或 Qt。

              如果分开,逻辑和GUI应该如何沟通? TCP/IP 套接字是一个不错的选择吗?还有哪些其他可能性?

              如果是本地通信,套接字是一个不错的选择或通过线程。

              让 GUI 使用不同于 C++ 的语言是个好主意吗?如果是 - 哪种语言?

              我认为这不是最好的选择。尽可能使用相同的语言。

              拥有基于浏览器的 GUI 是个好主意吗?

              只要不是太复杂。我认为基于浏览器的 GUI 仅适用于协作工具或绝对独立于平台(每个操作系统都有浏览器),只要您将主程序保存在服务器中。就像有人说avobe,如果你考虑做一个web GUI,首先考虑做一个webapp。

              尽管项目的核心逻辑是跨平台的,但我可以决定 GUI 将仅基于 Windows(.NET?),它将通过 Socket 与相关 Win/Linux 机器上的逻辑通信或类似的方法。这样做是个好主意吗?

              在我看来,它增加了复杂性,通常是不必要的,但如果你真的必须这样做,是的,套接字是最好的选择。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-04-07
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-06-22
                • 2012-02-23
                • 1970-01-01
                相关资源
                最近更新 更多