有关QSettings,qmlRegisterType()和setContextProperty的一些查询

时间:2013-08-09 17:24:07

标签: qt qml qsettings

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

我的应用程序(基于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的初始化细节。
  4. 在IRC上建议使用基于第3个选项的替代方法 - 如果没有参数传递给构造函数,则使用initFromSettings()类型的方法初始化实例。这样,初始化不会被隐藏,initFromSettings()可以自信地使用QSettings。现在,我可以愉快地使用qmlRegisterType()在QML中实例化OAuth2。

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

    此外,

    1. 将QSettings直接暴露给QML UI是一个好主意吗?
    2. 我个人更喜欢使用qmlRegisterType()来设置setContextProperty() - 这样,注册类实例的生命周期仅由QML维护。但是,由于缺少参数化构造函数的支持,前者不太可能被使用,除非使用某种形式的init() 显式初始化。这是一个很好的设计吗?
    3. 我提前为一篇令人难以忍受的长篇文章道歉。但我认为最好在这里问一下。

1 个答案:

答案 0 :(得分:0)

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

您想知道什么是好设计,但您没有指定目标。除非你可以列举目标,否则你无法真正评价它实现目标的程度。

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

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

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

这些用于公开c ++对象的工具也可以与社区分享。

祝你好运!