[Interest] Some questions on QSettings, qmlRegisterType() and setContextProperty

Mandeep Sandhu mandeepsandhu.chd at gmail.com
Sun Aug 11 12:44:06 CEST 2013


Have a look at O2, a Qt based OAuth library to see if it'll work for you:

https://github.com/pipacs/o2

It works well with QML, works with Qt4 & 5, stores tokens in (customizable)
QSettings in an encrypted form and has good support for OAuth 1 and 2.

HTH,
-mandeep






On Sat, Aug 10, 2013 at 11:05 AM, Jayesh Bhoot <mister.bhoot at gmail.com>wrote:

> Short, but informative reply. :)
>
> >
> > 2., but calling init in C++ componentComplete() (derive from
> > QQmlParserStatus as well) automatically, taking the input from
> > properties set in QML.
> >
> I want to clarify something here. The C++ OAuth2 class provides the data
> and logic to the OAuth2Browser QML window. It has a structure something
> like this:
>
> class OAuth2 : public QObject
> {
>      Q_OBJECT
>      Q_PROPERTY(QUrl oauthUrl READ oauthUrl)
>
> public:
>      explicit OAuth2(QObject *parent = 0);
>      explicit OAuth2(QString& appId, QUrl& redirectUrl, QStringList&
> permissions, QObject *parent = 0);
>
>      QUrl oauthUrl() const;
>
> signals:
>      void oauthSucceeded(QString userAccessToken);
>      void oauthFailed();
>
> public slots:
>      void onBrowsingUrlChanged(const QUrl& url);
>
> private:
>      QString parseUserAccessToken(const QUrl& url) const; // called by
> onBrowsingUrlChanged()
>
>      static const QString m_oauthEndPoint;
>      QString m_appId;
>      QUrl m_redirectUrl;
>      QStringList m_permissions;
>      QString m_userAccessToken;
> };
>
> This is how the QML class uses it:
>
> Window {
>      id: oauth2Browser
>      width: 500
>      height: 500
>
>      ColumnLayout {
>          anchors.fill: parent
>
>          WebView {
>              objectName: "Browser"
>              id: browser
>              Layout.fillHeight: true
>              Layout.fillWidth: true
>
>              url: oauth2.oauthUrl
>              onUrlChanged: oauth2.onBrowsingUrlChanged(browser.url)
>          }
>
>          Label {
>              id: loadingStatus
>              Layout.fillWidth: true
>              text: browser.loadProgress + "% loaded."
>          }
>      }
> }
>
> Thus, its the C++ class that sets the properties, and not the QML window
> that does it. By your method, I assumes that I would have to derive OAuth2
>  from QQmlParserStatus in order to track properties set by QML window.
> However, its the other way round - QML window takes data from an instance
> of the C++ class.
> How should I proceed then?
>
> Also, feel free to point out if my current design is flawed.
>
> > qmlRegisterType is better than setContextProperty, because that way
> > the flow is controlled from QML (and a lack of constructor arguments
> > is correct for declarative design, you can do additional property
> > based initialization in componentComplete). Good QML design has C++
> > expose functionality to QML but lets QML control the entire UI flow
> > (including window creation/handling).
>
> I agree with preferring qmlRegisterType over setContextProperty. But
> wouldn't your C++ QQmlParserStatus::componentComplete() approach work only
> if the data comes from QML to C++? I think that would be the case most of
> the time. But how should I handle the other way round, like in my case, or
> say, while grabbing data from database or application settings?
>
>
> >> 1. Is exposing QSettings directly to QML UI a good idea?
> >
> > Directly? Not a good idea, but possible. The new Qt.labs.settings API
> > aims to address this deficiency:
> > https://codereview.qt-project.org/#change,59149
>
> I will look forward to using this.
>
>
>
> On Sat, 10 Aug 2013 03:34:19 +0530, Alan Alpert <416365416c at gmail.com>
> wrote:
>
> > On Fri, Aug 9, 2013 at 8:12 AM, Jayesh Bhoot <mister.bhoot at gmail.com>
> > wrote:
> >> I will try explaining my confusion through the application I am
> >> currently
> >> developing.
> >>
> >> My application (based on Qt5.1 + Qt Quick Controls) interacts with
> >> Facebook API to manage a Facebook Page. I am trying to keep the QML code
> >> (for UI) as separate as possible from the C++ core.
> >>
> >> Now, an OAuth2 implementation is required to be able to interact with
> >> Facebook API. For that, I have a C++ OAuth2 class, the constructor of
> >> which has the following signature:
> >>
> >> OAuth2::OAuth2(QString appId, QString redirectUrl, QStringList
> >> permissions);
> >>
> >> Now, as the OAuth process requires a browser, I have also implemented an
> >> OAuthBrowser.qml, which uses OAuth2 to complete an authorization.
> >>
> >> I have the following options to expose OAuth2 class to OAuth2Browser:
> >>
> >> 1. Instantiate OAuth2 and use setContextProperty() to expose the
> >> instance
> >> to OAuth2Browser. However, this means my C++ code has to deal with the
> >> UI
> >> code. The more baffling issue is that OAuth2Browser is a secondary
> >> window.
> >> When a user clicks on a "Authorize" window on the MainWindow, then an
> >> AppController C++ object (connected to MainWindow) will launch the
> >> OAuth2Browser window. Thus, the instantiation code of OAuth2Browser
> >> would
> >> go deep down inside a AppController method. It would have been good if
> >> only main.cpp had to deal with the window creation.
> >>
> >> 2. Use qmlRegisterType(). In this case, I can't pass parameters to the
> >> constructor. So, I will have to implement an init() method that would
> >> initialize an OAuth2 object. Then, I would call this init() method in
> >> OAuth2Browser's Component.onCompleted() method.
> >> However, in this approach, I will have to expose QSettings to the UI
> >> code
> >> - QML window, so that the required parameters to init() method can be
> >> retrieved. I have huge skepticism on whether directly exposing
> >> application
> >> settings to QML UI is a good idea.
> >>
> >> 3. Implicitly use QSettings within the OAuth2 constructor. This way, I
> >> won't have to pass any parameters, and I would be able to use
> >> qmlRegisterType(). However, this means I am doing some magic stuff
> >> "behind
> >> the curtains". Instead of explicitly passing QSettings instance, I am
> >> using it wherever the hell I want to, thus hiding the initialization
> >> detail from public API.
> >>
> >> An alternative based on the 3rd option was advised on IRC - use an
> >> initFromSettings() type of method to initialize an instance if no
> >> parameter is passed to the constructor. That way, the initialization is
> >> not hidden, and initFromSettings() can confidently use QSettings within
> >> itself. Now, I can happily use qmlRegisterType() to instantiate OAuth2
> >> in
> >> QML.
> >>
> >> So, what is the better approach?
> >
> > 2., but calling init in C++ componentComplete() (derive from
> > QQmlParserStatus as well) automatically, taking the input from
> > properties set in QML.
> >
> >> Also,
> >> 1. Is exposing QSettings directly to QML UI a good idea?
> >
> > Directly? Not a good idea, but possible. The new Qt.labs.settings API
> > aims to address this deficiency:
> > https://codereview.qt-project.org/#change,59149
> >
> >> 2. I personally prefer qmlRegisterType() to setContextProperty() - that
> >> way, the lifetime of a registered class's instance is maintained solely
> >> by
> >> QML. However, the former is less likely to be used due to the lack of
> >> support of parameterized constructors, unless some form of init() is
> >> used
> >> explicitly for initialization. Is that a good design?
> >
> > qmlRegisterType is better than setContextProperty, because that way
> > the flow is controlled from QML (and a lack of constructor arguments
> > is correct for declarative design, you can do additional property
> > based initialization in componentComplete). Good QML design has C++
> > expose functionality to QML but lets QML control the entire UI flow
> > (including window creation/handling).
> >
> >>
> >> I apologise in advance for an excruciatingly long post. But I thought it
> >> best to ask here.
> >
> > Sorry for the excruciatingly short reply ;)
> >
> > --
> > Alan Alpert
>
>
> --
> Using Opera's mail client: http://www.opera.com/mail/
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20130811/97fd5424/attachment.html>


More information about the Interest mailing list