构建 Mac 和 Windows GUI 应用程序

2024-02-23

我计划为 Mac 和 Windows 构建一个 GUI 应用程序。我一直在技术选择方面进行一些研究,例如语言、库和构建工具,以便我可以在两个平台之间共享尽可能多的代码。

主要要求是:

  1. 满足 Mac App Store 要求。
  2. Mac 和 Windows 上的原生外观和感觉。
  3. Mac 上需要调用 Quartz Window Services,Windows 上需要调用 Windows API。
  4. 使用 SQLite 存储和读取数据。

我的帖子的长度已经失控,所以我将我的问题移到顶部作为摘要,而上下文则在下面。

问题

  1. 为了方便编程,我倾向于使用 Python。这对我来说是正确的选择吗?如果不是,为什么 C++ 会更好?如果是这样,我到底如何设置 py2app 和 pyobjc 来编译 python 并构建一个为 GUI 加载 XIB 的独立应用程序?
  2. 我不应该为了更原生的界面而在 Mac 上使用跨平台 GUI 库,对吗?或者我使用 QT 或 wxWidgets 会更好吗?
  3. 如果我走错了路和/或有我没有考虑过的更好的解决方案,请指出:)

到目前为止我的研究和结论

图形用户界面库

对于 Mac,我排除了使用跨平台 GUI 库(如 QT),因为它们似乎无法在 Mac 上提供本机外观和感觉(看起来不合适和/或很难编写遵循 Apple 的应用程序)人机界面指南)。 wxWidgets 说它使用本机库,但是这个post https://stackoverflow.com/a/4999048/1448071提到 wxPython 可能使用私有 Objective-C 调用,并且不太可能被批准用于 Mac App Store。最后,即使外观正确,两个平台的布局可能仍然需要有所不同。

因此,我计划对 Mac 界面使用原生 Cocoa GUI 库,但仍考虑对 Windows GUI 使用 wxWidgets。

Language

对于主要应用程序逻辑的语言,我的最佳选择似乎是 C++ 或 Python。显然,使用 Python 编写跨平台代码比使用 C++ 容易得多,但总是需要权衡。

Python

Pros:编写速度更快,维护也更容易。强大的跨平台库可以大大缩短开发时间。

Cons:使用Python意味着使用PyObjC,它已经一年多没有更新了(从svn可以看出),我不清楚它是否仍然可以与未来版本的Xcode和OSX一起使用。此外,要在 Xcode 之外使用 PyObjc 和 py2app 设置任何健全的构建配置并使用 xibs 作为 GUI,都是一场噩梦。

C++

Pros:在 Mac 和 Windows 上更轻松地设置构建配置和依赖项。运行速度比 Python 快得多,但就我而言,性能并不是一个大问题。

Cons:我不懂C++。我很擅长 C,但看起来这对我编写优秀的 C++ 没有多大帮助。我的总体印象是编写跨平台 C++ 要困难得多,但我可能是错的。有很多关于模糊错误的帖子。不过,Boost 看起来很有希望。

构建工具

如果使用 C++ 作为主要语言,那么在这两个平台上进行设置似乎都很简单。如果我使用 Python,那么在 Windows 上设置似乎也很简单,因为我将使用 wxWidgets 作为 GUI 并使用 py2exe 进行部署。

至于Mac和Python,标准选择似乎是pyobjc和py2app。不幸的是,我还没有找到任何使用 XIB 和 Cocoa 库而不是 QT 或 wxWidgets 的 py2app 构建配置的示例。我不希望 Xcode 管理构建,因为我更喜欢将 Python 文件和应用程序资源放置在 Xcode 之外 Xcode 项目目录。这将大大简化 Windows 的设置并使文件树更清晰。

关于QT的编辑:我又看了一眼 QT,花了几个小时和 QT 设计器一起玩。基本的 UI 元素(按钮、文本字段、标签)看起来与 Cocoa 元素相同。我轻松地将 QWindow 和 QTabView 与一些元素组合在一起,它看起来像一个 Cocoa 应用程序。然而,也有一些负面影响:

  • 行为有点不对劲,比如缺乏弹性滚动,QTextEdit 没有指示焦点的蓝色阴影。
  • QTableView 看起来不太像它的 Cocoa 对应物。
  • 元素之间的间距、父视图的间距不遵循准则。它主要可以通过调整布局来修复,但需要在任何地方完成,我可以通过 Xcode 免费获得它。
  • 缺少用于制作检查员的 HUD 元素。这是我的应用程序中很可能需要的东西,至少对于 Mac 端来说是这样。
  • 辅助功能支持较差。

我知道我很挑剔,但需要挑剔才能做出好的用户界面。总的来说,QT 对于 Windows 来说似乎是一个很好的解决方案,但我想我会坚持使用 Cocoa for Mac。我对现有程序做了一些额外的研究,发现VLC http://wiki.videolan.org/Interfaces, Chrome https://stackoverflow.com/questions/874609/which-gui-library-does-google-chrome-use, and 传播 http://www.transmissionbt.com/所有这些都为 Mac 制作本机 GUI,而 VLC 使用 QT for Windows,Chrome 使用自定义框架,Transmission 使用 GTK+ 和 QT for Linux。

我想我已经决定在 Mac 上使用 Cocoa GUI,在 Windows 上使用 Qt 或 wxWidgets,但仍然在 C++ 和 Python 之间划分共享逻辑。


我认为您可能太快地排除了 Qt。这guy https://stackoverflow.com/a/5430867/245265据报道,他在 Mac App Store 上发布了一款基于 Qt 的应用程序。

据此相关answer https://stackoverflow.com/a/10767009/245265,您可以指定 Qt 构建目标以使用 Cocoa 而不是已弃用的 Carbon API。

This Qt bug https://bugreports.qt-project.org/browse/QTBUG-165494.8 版本中解决了某些 plist 文件将被写入未经 Apple 批准的位置的问题。

This Qt文章 https://web.archive.org/web/20120609170628/http://doc.qt.nokia.com/qq/qq18-macfeatures.html讨论为支持 Mac 原生外观而引入的特殊功能。


对于 C++,如果您使用 Qt 或 Boost 等库来抽象出与平台相关的位(例如 Boost.Asio、Boost.Filesystem 和 Boost.Thread,Qt 有类似的库),通常不会出现跨平台问题。网络、文件和线程的抽象)。

C++绝对是一种“专家友好”的语言。如果可以使用 Qt 的 Python 和 PySide 绑定,同时仍然能够发布到 App Store,那么我猜这可能是您最好的选择。

如果您最终使用 C++,那么我强烈建议您学习使用您可以使用的所有工具,这将最大限度地减少手动内存管理和原始指针。了解容器类、字符串类和智能(引用计数)指针。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

构建 Mac 和 Windows GUI 应用程序 的相关文章

  • Pandas:将 pytz.FixedOffset 应用于系列

    我有一个带有timestamp列看起来像这样 0 2020 01 26 05 00 00 08 00 1 2020 01 26 06 00 00 08 00 Name timestamp dtype datetime64 ns pytz F
  • 检查 RoutedEvent 是否有任何处理程序

    我有一个自定义 Button 类 当单击它时 打开特定窗口 它总是执行相同的操作 我添加了一个可以在按钮的 XAML 中分配的 Click 事件 就像常规按钮一样 当它被单击时 我想执行 Click 事件处理程序 如果已分配 否则我想执行默
  • 将列表中的 None 替换为最左边的非 none 值

    Given a None 1 2 3 None 4 None None I d like a None 1 2 3 3 4 4 4 目前我已经用以下方法强制它 def replaceNoneWithLeftmost val last Non
  • uri 警告中缺少端口:使用 Python OpenCV cv2.VideoCapture() 打开文件时出错

    当我尝试流式传输 ipcam 时 出现了如下所示的错误 tcp 000000000048c640 uri 中缺少端口 警告 打开文件时出错 build opencv modules videoio src cap ffmpeg impl h
  • 为什么 __instancecheck__ 没有被调用?

    我有以下 python3 代码 class BaseTypeClass type def new cls name bases namespace kwd result type new cls name bases namespace p
  • 用于多个窗口的 Tkinter 示例代码,为什么按钮无法正确加载?

    我正在编写一个程序 应该 按一下按钮即可打开一个窗口 按另一个按钮关闭新打开的窗口 我使用类 以便稍后可以将代码插入到更大的程序中 但是 我无法正确加载按钮 import tkinter as tk class Demo1 tk Frame
  • 在seaborn中对箱线图x轴进行排序

    我的数据框round data看起来像这样 error username task path 0 0 02 n49vq14uhvy93i5uw33tf7s1ei07vngozrzlsr6q6cnh8w 39 png 1 0 10 n49vq
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 计算 pyspark df 列中子字符串列表的出现次数

    我想计算子字符串列表的出现次数 并根据 pyspark df 中包含长字符串的列创建一个列 Input ID History 1 USA UK IND DEN MAL SWE AUS 2 USA UK PAK NOR 3 NOR NZE 4
  • 在python中读取PASCAL VOC注释

    我在 xml 文件中有注释 例如这个 它遵循 PASCAL VOC 约定
  • C# 中的 strstr() 等效项

    我有两个byte 我想找到第二个的第一次出现byte 在第一个byte 或其中的一个范围 我不想使用字符串来提高效率 翻译第一个byte to a string会效率低下 基本上我相信就是这样strstr 在 C 中做 最好的方法是什么 这
  • 在Python中连续解析文件

    我正在编写一个脚本 该脚本使用 HTTP 流量行解析文件 并取出域 目前仅将它们打印到屏幕上 我正在使用 httpry 将流量连续写入文件 这是我用来删除域名的脚本 usr bin python import re input open r
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • 如何使用 os.chdir 转到减去最后一步的路径?

    例如 一个方法传递了一个路径作为参数 这个路径可能是 C a b c d 如果我想使用 os chdir 更改为 C a b 怎么办 c 没有最后一个文件夹 os chdir 可以接受 命令吗 os chdir 可以采取 作为论点 是的 然
  • Python:无法使用 os.system() 打开文件

    我正在编写一个使用该应用程序的 Python 脚本pdftk http www pdflabs com tools pdftk the pdf toolkit 几次来执行某些操作 例如 我可以在 Windows 命令行 shell 中使用
  • 更新 SQLAlchemy 中的特定行

    我将 SQLAlchemy 与 python 一起使用 我想更新表中等于此查询的特定行 UPDATE User SET name user WHERE id 3 我通过 sql alchemy 编写了这段代码 但它不起作用 session
  • 如何更改matplotlib中双头注释的头大小?

    Below figure shows the plot of which arrow head is very small 我尝试了下面的代码 但它不起作用 它说 引发 AttributeError 未知属性 s k 属性错误 未知属性头宽
  • 在父类中访问子类变量

    我有一个父类和一个继承的子类 我想知道如何访问我的父类中的子类变量 我尝试了这个但失败了 class Parent object def init self print x class Child Parent x 1 x Child Er
  • 使用 SERVER_NAME 时出现 Flask 404

    在我的 Flask 配置中 我将 SERVER NAME 设置为 app example com 之类的域 我这样做是因为我需要使用url for with external网址 如果未设置 SERVER NAME Flask 会认为服务器
  • 将 char[][] 转换为 char** 会导致段错误吗?

    好吧 我的 C 有点生疏了 但我想我应该用 C 来做我的下一个 小 项目 这样我就可以对其进行抛光 并且我已经有不到 20 行的段错误了 这是我的完整代码 define ROWS 4 define COLS 4 char main map

随机推荐

  • 在 PostScript 中显示 Unicode 字符

    如何让我的 PostScript 程序显示 G 谱号字符Bravura https github com steinbergmedia bravura字体 根据这个SMuFL http www smufl org files smufl 0
  • 如何取数据?

    我正在学习使用神经网络 并且遇到了问题 我不知道如何转换神经网络的数据 据我了解 我需要对数据进行标准化 在标准化和学习之后 答案总是平均的 https jsfiddle net eoy7krzj https jsfiddle net eo
  • 奇怪的方法行为 - 函数的 ToString

    考虑这个代码片段 class Program static void Main string args Console WriteLine Test ToString static IEnumerable
  • 如何使用 Azure API Manager 缓存存储值策略存储 JSON 有效负载?

    再会 我尝试使用 缓存存储值 策略将传入的 JSON 负载存储到 Azure API Manager 内部缓存中 密钥将是有效负载内的字段之一 我能够提取密钥 但是当我尝试存储有效负载时 我收到错误 表达式求值失败 未将对象引用设置为对象的
  • 尝试使用 SQL 从多个表中删除

    我的应用程序中有 4 个表 User usession upklist 项目共享 最后三个表包含一个名为session id 在下面的代码中 括号中的部分用于获取所有session id值来自usession用户 awpeople 的表 问
  • Apache Beam 每用户会话窗口未合并

    我们有一个有用户的应用程序 每个用户每次使用我们的应用程序大约 10 40 分钟 我想根据发生的特定事件 例如 该用户已转换 该用户上次会话出现问题 该用户上次会话成功 在此之后 我想计算每天这些更高级别的事件 但这是一个单独的问题 为此
  • 如何在 Jupyter 中将变量从 javascript 传递到 python?

    据我了解 我应该能够打印变量foo在下面的代码片段中 from IPython display import HTML HTML print foo 相反 我看到以下错误消息 NameErrorTraceback most recent c
  • 在.NET中设置打印机“保留打印文档”属性

    这就是我们正在尝试做的事情 我们希望以一种不引人注目的方式获取客户在其计算机上打印的所有内容 我们所有的客户都运行 POS 系统并专门使用 Windows XP 并将其发送给我们 我们决定最好的方法是创建一个 c 向我们发送假脱机文件的应用
  • 如何将文本 URL 转换为 PHP 页面中的可点击链接?

    我确信这是一个非常简单 明显的答案 但我的大脑已经崩溃了 我似乎无法理解它 我有一个 PHP 站点 允许用户将信息发布到 mySQL 中的文本字段 这些帖子都可以在线查看 在发布 编辑模式下 该字段是 HTML 表单中的文本区域 在阅读模式
  • 在开发环境中覆盖ActionMailer的邮件地址

    在我的开发环境中 我在本地测试时使用生产数据库的副本 出于测试和防止向真实用户发送测试 开发电子邮件的原因 在开发模式下覆盖邮件地址的最佳方法是什么 我知道我可以在每个邮件程序中编写逻辑 但我有几个 最好将它们全部放在一个地方 我可以覆盖m
  • IllegalArgumentException:在 ViewPager 中找不到片段 id 的视图 --- ViewPager

    我遇到了困扰我好几天的问题 有一个ViewPager在主要活动中持有 3Fragments 作为选项卡片段 在里面first片段有一个ListView哪个持有一些观点 哪个是最重要的 另一个ViewPager 我想在子里保留一些照片View
  • 如何在本地测试并发?

    本地测试并发的最佳方法是什么 即我想测试 10 个并发点击 我知道类似的服务Blitz http blitz io 然而 我试图找到一种更简单的方法在本地进行测试以对抗竞争条件 有任何想法吗 也许通过卷曲 查看 Apache Bench a
  • 如何从 csv 文件读取表格中的文本

    我是新使用 tm 包 我想读取一个 csv 文件 其中一列包含 2000 个文本 第二列包含因子变量 yes no 到语料库中 我的目的是将文本转换为矩阵并使用因子变量作为预测目标 我还需要将语料库划分为训练集和测试集 我阅读了一些文档 例
  • GROUP BY 子句在 sqlite 中获取逗号分隔值

    我的表结构是这样的 使用sqlite3 CREATE TABLE enghindi eng TEXT hindi TEXT 我有一张名为enghindi其中有两列名为hindi eng 我想合并 eng 列的记录 并通过逗号分隔合并印地文单
  • 如果没有人调用interrupt(),可以忽略InterruptedException吗?

    如果我创建自己的线程 即不是线程池 并且在某个地方调用sleep或任何其他可中断方法 是否可以忽略 InterruptedException如果我知道代码中没有其他人在线程上进行中断 换句话说 如果线程的寿命应该与 JVM 一样长 这意味着
  • 如何让 PHP SOAP 客户端与使用无效证书通过 SSL 运行的服务进行通信

    我尝试使用 PHP SOAP 客户端使用 SOAP 服务 但失败并显示以下消息 SoapFault SOAP ERROR Parsing WSDL Couldn t load from https domain com webservice
  • MathJax 渲染模糊

    MathJax http www mathjax org 在浏览器中的渲染 右 比在 LaTeX 中的等效 PDF 渲染 左 要模糊得多 这是 Javascript 限制 浏览器限制 MathJax 限制 错误 设计原因还是其他原因 有什么
  • 创建 AMI 映像作为 cloudformation 堆栈的一部分

    我想创建一个 EC2 cloudformation 堆栈 基本上可以按以下步骤描述 1 启动实例 2 配置实例 3 停止实例并从中创建 AMI 映像 4 使用创建的 AMI 映像作为源创建自动缩放组以启动新实例 基本上我可以在一个 clou
  • 当我需要转义 Html 字符串时?

    在我的遗留项目中 我可以在字符串发送到浏览器之前看到 escapeHtml 的用法 StringEscapeUtils escapeHtml stringBody 我从 api 文档知道 escapeHtml 的作用 这里是给出的示例 Fo
  • 构建 Mac 和 Windows GUI 应用程序

    我计划为 Mac 和 Windows 构建一个 GUI 应用程序 我一直在技术选择方面进行一些研究 例如语言 库和构建工具 以便我可以在两个平台之间共享尽可能多的代码 主要要求是 满足 Mac App Store 要求 Mac 和 Wind