Lazy programmers and Q_PROPERTY

Yesterday I started tryign to help the plasma team with the KCM migration, as there are many KCM’s and it’s a tedious process to port something from QWidgets to Qml. The biggest part of the tediousness of the process is to create a QObject that has all the properties that the Qml-based KCM needs to change, and for a simple QProperty you have at least this code for the header:

Q_PROPETY(QString name READ name WRITE setName NOTIFY setNameChanged)
QString name() const;
void setName(const QString& name);
signals: 
void nameChanged(const QString& name);
private:
QString _name;

and this snippet for the implementation.

QString MyClass::name() const
{
     return _name;
}

void MyClass::setName(const QString& value)
{
     if (_name==value) {
         return;
     }
    _name = value;
    emit nameChanged(value);
}

The code is easy, is straigthforward and it’s simple to write, so why I’m complaining? I’m complaining because I’m Lazy. and I don’t like to do more work than necessary, and I’m also a progrmmer so I know that this can be overly simplified. On the first KCM that I started to port there’s around 30 properties, if I would write from scratch all the setters, getters, signals I would have written around 550 lines of code, for just 30 properties. I talked to marco that I would take the time to write a generator for that, as I was unhappy with the current approach, and today I revived my meta-qsettings generator to generate simple QObject-based classes that have signal / slots.

The above example would be written as:

MyClass {
    QString name
}

Then you would need to run the qtobjgen on the file and as output you get the header/source pair where you can start to hack, but the boilerplate would be already done. Now, I don’t plan that people would keep the template files for the code generation on the repo, this is just the first step to generate a lot of boilerplate quickly.

If you wanna try, the code is currently in my evil-github here

I don’t plan to write Q_PROPERTY manually again.

Too old for that.

6 Responses to “Lazy programmers and Q_PROPERTY

  • David Edmundson
    2 months ago

    You can also do

    Q_PROPETY(QString name MEMBER m_name NOTIFY nameChanged)
    Q_SIGNALS:
    void nameChanged();
    private:
    QString m_name

    I don’t know why we don’t use that more in Plasma, personally I use it everywhere.

    It’s a tiiiny bit more code than yours, but also solves the situation where you want to generate most and have one custom setBlahBlah

    • tcanabrava
      2 months ago

      That work if you don’t have some logic you wanna add to the set and you still need to define the property, member variable and notification signal.

  • Giuseppe
    2 months ago

    For the record, note that in Creator (and likely also in KDevelop) you can start writin Q_PROP and accept one of the autocompletion proposals, that will just ask for the type and the name of the property, and automatically generate the name of the READ / WRITE / NOTIFY functions (following Qt’s style).

    In other words: just write Q_PROP, get the autocompletion, accept the autocompletion option and you’ll be able to just input type and name (in your case, “QString” and “name”), and Creator will fill the Q_PROPERTY line itself.

    Once that’s done, go at the end of the line (after the closing )), and hit alt+enter to trigger autocompletion again, and select “Generate missing property members”, and voilà, you’ll have everything generated for you.

    Hope this helps.

    • tcanabrava
      2 months ago

      It does help, What’s the output of the cpp part? that’s what I’m most interested in.

      • Giuseppe
        2 months ago

        Exactly the one you wrote above. Try it for yourself…

        • tcanabrava
          2 months ago

          That’s really nice to know. So I went to try on QtCreator, the Q_PROPERTY line it correctly did
          When triggered the “Generate missing property members” I found a few issues with it:

          1 – It generate the members in the header and that’s something I do not want (header / source separation exists for a reason)
          2 – It passed my QString by copy instead of const-ref
          3 – I had a variable _property and it created anotyer m_property.

          Overall quite good knowing that it exists but for a result I still prefer mine.
          In due time I’ll try to fix those noiseances in QtCreator.

Leave a Reply

Your email address will not be published. Required fields are marked *