3

我将尝试通过我目前正在开发的应用程序来解释我的困惑。

我的应用程序(基于 Qt5.1 + Qt Quick Controls)与 Facebook API 交互以管理 Facebook 页面。我试图将 QML 代码(用于 UI)与 C++ 核心尽可能分开。

现在,需要 OAuth2 实现才能与 Facebook API 交互。为此,我有一个 C++ OAuth2 类,其构造函数具有以下签名:

OAuth2::OAuth2(QString appId, QString redirectUrl, QStringList 权限);

现在,由于 OAuth 过程需要一个浏览器,我还实现了一个 OAuthBrowser.qml,它使用 OAuth2 来完成授权。

我有以下选项可以将 OAuth2 类公开给 OAuth2Browser:

  1. 实例化 OAuth2 并使用 setContextProperty() 将实例公开给 OAuth2Browser。但是,这意味着我的 C++ 代码必须处理 UI 代码。更令人费解的问题是 OAuth2Browser 是一个辅助窗口。当用户单击 MainWindow 上的“授权”窗口时,
    AppController C++ 对象(连接到 MainWindow)将启动 OAuth2Browser 窗口。因此,OAuth2Browser 的实例化代码将深入到 AppController 方法中。如果只有 main.cpp 必须处理窗口创建,那就太好了。
  2. 使用 qmlRegisterType()。在这种情况下,我无法将参数传递给构造函数。所以,我必须实现一个初始化 OAuth2 对象的 init() 方法。然后,我会在 OAuth2Browser 的 Component.onCompleted() 方法中调用这个 init() 方法。但是,在这种方法中,我必须将 QSettings 暴露给 UI 代码 - QML 窗口,以便 init() 方法所需的参数可以被取回。我非常怀疑将应用程序设置直接暴露给 QML UI 是否是一个好主意。
  3. 在 OAuth2 构造函数中隐式使用 QSettings。这样,我就不必传递任何参数,并且可以使用 qmlRegisterType()。然而,这意味着我正在“幕后”做一些神奇的事情。我没有显式传递 QSettings 实例,而是在任何我想使用的地方使用它,从而对公共 API 隐藏了初始化细节。

在 IRC 上建议了基于第三个选项的替代方案 - 如果没有将参数传递给构造函数,则使用 initFromSettings() 类型的方法来初始化实例。这样,初始化不会被隐藏,并且 initFromSettings() 可以自信地在其内部使用 QSettings。现在,我可以愉快地使用 qmlRegisterType() 在 QML 中实例化 OAuth2。

那么,更好的方法是什么?

还,

  1. 将 QSettings 直接暴露给 QML UI 是个好主意吗?
  2. 我个人更喜欢 qmlRegisterType() 到 setContextProperty() - 这样,注册类实例的生命周期仅由 QML 维护。但是,由于缺乏对参数化构造函数的支持,前者不太可能使用,除非
    显式使用某种形式的 init() 进行初始化。这是一个好的设计吗?

我提前为一篇冗长的帖子道歉。但我认为最好在这里问。

4

1 回答 1

0

很难完全关注您的帖子,因为它太长且信息密集。以下是我对它们可能价值的建议。

你想知道什么是好的设计,但你没有明确你的目标。除非你能列举出目标,否则你无法真正评价它实现目标的程度。

您正在处理 facebook 的 api。我的水晶球说改变是你需要处理的事情。因此,将所有工具放入 qml 可能会让您更好地响应变化。您可以通过在 qml 文件中重写 javascript 而不是重新编译(希望如此)来响应更改。使用属性和信号/插槽设计,它应该足够灵活以完成工作。性能似乎不是问题。

我会创建一个设置对象来公开您要存储的内容。也许使用 Qt 已经提供的模型/视图架构。底层存储、xml 文件、数据库、QSettings 注册表并不重要。您可以提供一个网格/列表,以允许用户在必要时更新他们的设置。

将 oauth 和浏览器工具作为对象放在一起,让您可以在 qml 中编写应用程序的行为脚本。

这些暴露 c++ 对象的工具也可能非常适合与社区分享。

祝你好运!

于 2013-09-04T18:11:15.277 回答