Qt Property Generator



  • Following a proposal I made "here":http://qt-project.org/forums/viewthread/23684/, I created a simple tool to automate the creation of Q_PROPERTY properties:

    !http://i50.tinypic.com/1y4b2o.png(qt property generator)!
    !http://i49.tinypic.com/4ttz42.png(qt property generator)!

    Although far from perfect, it should be usable to save some time when creating properties, which is quite often with Qt.

    It is really simple to use, just type in the name and type of the property, and select the appropriate checkboxes to generate the needed code.

    The text fields have an identifier validation with automatic camel casing, so if you type "my property" it will be converted to myProperty, as well as filtering occasional numbers in the beginning of the identifier, after the first character numbers are legal.

    The Chain option alters the setter to return a reference to the object, which needs to be specified in the "Class name" field, in order to allow chaining:

    @myObject.setNumber(1).setColor(Qt::red).setSize(20);@

    For notification, you can select only to emit a signal, or the signal with the value or value reference.

    Arbitrary number of properties can be generated at once.
    It is possible to chose between inline definitions in the header and regular definitions in the cpp.
    It is possible to chose whether property code is packed per property or per property component.

    You can "get the source here":https://github.com/ddriver/propertygenerator and build it yourself, should build fine with both Qt4 and Qt5.


  • Moderators

    Looks good, thanks for doing this and sharing.



  • First of all: thanks for taking this initiative.

    • Could you say why the getter is a Q_SLOT?
    • Shouldn't the getter be const?
    • Would it be possible to specify if the code should be inlined or defined in the implementation file?
    • Would it be possible to extend the setter to something like this:
      @
      MyClass::setFrameSize(const QSize &v) {
      if (m_frameSize != v) {
      m_frameSize = v;
      emit frameSizeChanged(m_frameSize); //only emit if the value is actually different
      }
      return *this;
      @

    I assume that for now, this is a generator only, and the app does not allow modifying properties in existing code, right? That would make it really cool...

    Integration into Qt Creator would be a must for me to make this really useful.



  • ^^ - Did it real quick and it was really late, will do some fixes when I get the time.

    And no, it won't work for existing code. On a related note - is there an API I can use to get the Creator "intellisense" information? Well, I know there is one, since the functionality exist, I just wonder if it is a public and documented one.



  • I'd ask around at #qt-creator on IRC (freenode network) for that.



  • OK, fixed a few things:

    • getter is no longer slot

    • getter is const

    • setter checks if the value is different

    @// Auto generated property dateOfBirth : QDate
    Q_PROPERTY(QDate dateOfBirth READ dateOfBirth WRITE setDateOfBirth RESET resetDateOfBirth NOTIFY dateOfBirthChanged)
    private: QDate m_dateOfBirth;

    public: inline QDate dateOfBirth() const {
    return m_dateOfBirth;
    }
    Q_SLOT Person &setDateOfBirth(const QDate &v) {
    if (m_dateOfBirth != v) {
    m_dateOfBirth = v;
    emit dateOfBirthChanged(m_dateOfBirth);
    }
    return *this;
    }
    Q_SLOT inline void resetDateOfBirth() {
    // TODO reset
    }
    Q_SIGNAL void dateOfBirthChanged(QDate);@


  • Moderators

    Shouldn't the getter be at least a Q_INVOKABLE?



  • [quote author="sierdzio" date="1360670794"]Shouldn't the getter be at least a Q_INVOKABLE?[/quote]

    Why would it need to?



  • It would make sense to be Q_INVOKABLE if it wasn't a property to begin with, you know... to use in QML and in the designer. But it is a property so this is taken care of.


  • Moderators

    OK. Guess I've always been adding it without actually testing if it's required ;)



  • I improved the tool by adding some functionality:

    • now it can generate an arbitrary number of properties at the same time

    • it is possible to chose between inline definitions in the header or only declarations in the header and definitions in the cpp

    • properties can be grouped - the generated source is packed for each property, or non-grouped and the code is not packed for each property but for each property component

    I also added a link for a pre-build executable for windows in the first post.

    It is still all pretty crude, but in this form the tool is considerably more useful and can generate a considerable amount of code with just a few mouse clicks, thus saving considerable time as well.

    !http://i45.tinypic.com/105tzzo.png(p1)!
    !http://i45.tinypic.com/6z7jgo.png(p2)!
    !http://i46.tinypic.com/16gh6rd.png(p3)!



  • And the resulting code:

    inline non-grouped:
    @//Auto-generated properties:
    Q_PROPERTY(int number READ number WRITE setNumber RESET resetNumber NOTIFY numberChanged REVISION 1)
    Q_PROPERTY(QColor color READ color WRITE setColor RESET resetColor NOTIFY colorChanged)
    Q_PROPERTY(QSize size READ size WRITE setSize RESET resetSize NOTIFY sizeChanged)
    Q_PROPERTY(uint id READ id CONSTANT)
    Q_PROPERTY(QString name READ name WRITE setName RESET resetName NOTIFY nameChanged)
    Q_PROPERTY(qreal real READ real WRITE setReal RESET resetReal NOTIFY realChanged DESIGNABLE false SCRIPTABLE false)

    private:
    int m_number;
    QColor m_color;
    QSize m_size;
    uint m_id;
    QString m_name;
    qreal m_real;

    public:
    inline int number() const {
    return m_number;
    }

    inline QColor color() const {
    return m_color;
    }

    inline QSize size() const {
    return m_size;
    }

    inline uint id() const {
    return m_id;
    }

    inline QString name() const {
    return m_name;
    }

    inline qreal real() const {
    return m_real;
    }

    Q_SLOT TestClass &setNumber(const int &v) {
    if (m_number != v) {
    m_number = v;
    emit numberChanged(m_number);
    }
    return *this;
    }

    Q_SLOT TestClass &setColor(const QColor &v) {
    if (m_color != v) {
    m_color = v;
    emit colorChanged(m_color);
    }
    return *this;
    }

    Q_SLOT TestClass &setSize(const QSize &v) {
    if (m_size != v) {
    m_size = v;
    emit sizeChanged(m_size);
    }
    return *this;
    }

    Q_SLOT TestClass &setName(const QString &v) {
    if (m_name != v) {
    m_name = v;
    emit nameChanged(m_name);
    }
    return *this;
    }

    Q_SLOT TestClass &setReal(const qreal &v) {
    if (m_real != v) {
    m_real = v;
    emit realChanged(m_real);
    }
    return *this;
    }

    Q_SLOT void resetNumber() {
    //TODO reset
    }

    Q_SLOT void resetColor() {
    //TODO reset
    }

    Q_SLOT void resetSize() {
    //TODO reset
    }

    Q_SLOT void resetName() {
    //TODO reset
    }

    Q_SLOT void resetReal() {
    //TODO reset
    }

    Q_SIGNAL void numberChanged(int);
    Q_SIGNAL void colorChanged(QColor &);
    Q_SIGNAL void sizeChanged(QSize &);
    Q_SIGNAL void nameChanged(QString &);
    Q_SIGNAL void realChanged(qreal);
    @

    inline grouped:
    @
    //Auto-generated property number : int
    Q_PROPERTY(int number READ number WRITE setNumber RESET resetNumber NOTIFY numberChanged REVISION 1)
    private: int m_number;
    public: inline int number() const {
    return m_number;
    }

    Q_SLOT TestClass &setNumber(const int &v) {
    if (m_number != v) {
    m_number = v;
    emit numberChanged(m_number);
    }
    return *this;
    }

    Q_SLOT void resetNumber() {
    //TODO reset
    }

    Q_SIGNAL void numberChanged(int);

    //Auto-generated property color : QColor
    Q_PROPERTY(QColor color READ color WRITE setColor RESET resetColor NOTIFY colorChanged)
    private: QColor m_color;
    public: inline QColor color() const {
    return m_color;
    }

    Q_SLOT TestClass &setColor(const QColor &v) {
    if (m_color != v) {
    m_color = v;
    emit colorChanged(m_color);
    }
    return *this;
    }

    Q_SLOT void resetColor() {
    //TODO reset
    }

    Q_SIGNAL void colorChanged(QColor &);

    //Auto-generated property size : QSize
    Q_PROPERTY(QSize size READ size WRITE setSize RESET resetSize NOTIFY sizeChanged)
    private: QSize m_size;
    public: inline QSize size() const {
    return m_size;
    }

    Q_SLOT TestClass &setSize(const QSize &v) {
    if (m_size != v) {
    m_size = v;
    emit sizeChanged(m_size);
    }
    return *this;
    }

    Q_SLOT void resetSize() {
    //TODO reset
    }

    Q_SIGNAL void sizeChanged(QSize &);

    //Auto-generated property id : uint
    Q_PROPERTY(uint id READ id CONSTANT)
    private: uint m_id;
    public: inline uint id() const {
    return m_id;
    }

    //Auto-generated property name : QString
    Q_PROPERTY(QString name READ name WRITE setName RESET resetName NOTIFY nameChanged)
    private: QString m_name;
    public: inline QString name() const {
    return m_name;
    }

    Q_SLOT TestClass &setName(const QString &v) {
    if (m_name != v) {
    m_name = v;
    emit nameChanged(m_name);
    }
    return *this;
    }

    Q_SLOT void resetName() {
    //TODO reset
    }

    Q_SIGNAL void nameChanged(QString &);

    //Auto-generated property real : qreal
    Q_PROPERTY(qreal real READ real WRITE setReal RESET resetReal NOTIFY realChanged DESIGNABLE false SCRIPTABLE false)
    private: qreal m_real;
    public: inline qreal real() const {
    return m_real;
    }

    Q_SLOT TestClass &setReal(const qreal &v) {
    if (m_real != v) {
    m_real = v;
    emit realChanged(m_real);
    }
    return *this;
    }

    Q_SLOT void resetReal() {
    //TODO reset
    }

    Q_SIGNAL void realChanged(qreal);

    @



  • non-inline non-grouped:
    @// header
    //Auto-generated properties:
    Q_PROPERTY(int number READ number WRITE setNumber RESET resetNumber NOTIFY numberChanged REVISION 1)
    Q_PROPERTY(QColor color READ color WRITE setColor RESET resetColor NOTIFY colorChanged)
    Q_PROPERTY(QSize size READ size WRITE setSize RESET resetSize NOTIFY sizeChanged)
    Q_PROPERTY(uint id READ id CONSTANT)
    Q_PROPERTY(QString name READ name WRITE setName RESET resetName NOTIFY nameChanged)
    Q_PROPERTY(qreal real READ real WRITE setReal RESET resetReal NOTIFY realChanged DESIGNABLE false SCRIPTABLE false)

    private:
    int m_number;
    QColor m_color;
    QSize m_size;
    uint m_id;
    QString m_name;
    qreal m_real;

    public:
    int number() const;
    QColor color() const;
    QSize size() const;
    uint id() const;
    QString name() const;
    qreal real() const;

    Q_SLOT TestClass &setNumber(const int &v);
    Q_SLOT TestClass &setColor(const QColor &v);
    Q_SLOT TestClass &setSize(const QSize &v);
    Q_SLOT TestClass &setName(const QString &v);
    Q_SLOT TestClass &setReal(const qreal &v);

    Q_SLOT void resetNumber();
    Q_SLOT void resetColor();
    Q_SLOT void resetSize();
    Q_SLOT void resetName();
    Q_SLOT void resetReal();

    Q_SIGNAL void numberChanged(int);
    Q_SIGNAL void colorChanged(QColor &);
    Q_SIGNAL void sizeChanged(QSize &);
    Q_SIGNAL void nameChanged(QString &);
    Q_SIGNAL void realChanged(qreal);

    // source
    int TestClass::number() const {
    return m_number;
    }

    QColor TestClass::color() const {
    return m_color;
    }

    QSize TestClass::size() const {
    return m_size;
    }

    uint TestClass::id() const {
    return m_id;
    }

    QString TestClass::name() const {
    return m_name;
    }

    qreal TestClass::real() const {
    return m_real;
    }

    TestClass &TestClass::setNumber(const int &v) {
    if (m_number != v) {
    m_number = v;
    emit numberChanged(m_number);
    }
    return *this;
    }

    TestClass &TestClass::setColor(const QColor &v) {
    if (m_color != v) {
    m_color = v;
    emit colorChanged(m_color);
    }
    return *this;
    }

    TestClass &TestClass::setSize(const QSize &v) {
    if (m_size != v) {
    m_size = v;
    emit sizeChanged(m_size);
    }
    return *this;
    }

    TestClass &TestClass::setName(const QString &v) {
    if (m_name != v) {
    m_name = v;
    emit nameChanged(m_name);
    }
    return *this;
    }

    TestClass &TestClass::setReal(const qreal &v) {
    if (m_real != v) {
    m_real = v;
    emit realChanged(m_real);
    }
    return *this;
    }

    int TestClass::resetNumber() {
    //TODO reset
    }

    QColor TestClass::resetColor() {
    //TODO reset
    }

    QSize TestClass::resetSize() {
    //TODO reset
    }

    QString TestClass::resetName() {
    //TODO reset
    }

    qreal TestClass::resetReal() {
    //TODO reset
    }
    @

    non-inline grouped:
    @//header
    //Auto-generated property number : int
    Q_PROPERTY(int number READ number WRITE setNumber RESET resetNumber NOTIFY numberChanged REVISION 1)
    private: int m_number;
    public: int number() const;
    Q_SLOT TestClass &setNumber(const int &v);
    Q_SLOT void resetNumber();
    Q_SIGNAL void numberChanged(int);

    //Auto-generated property color : QColor
    Q_PROPERTY(QColor color READ color WRITE setColor RESET resetColor NOTIFY colorChanged)
    private: QColor m_color;
    public: QColor color() const;
    Q_SLOT TestClass &setColor(const QColor &v);
    Q_SLOT void resetColor();
    Q_SIGNAL void colorChanged(QColor &);

    //Auto-generated property size : QSize
    Q_PROPERTY(QSize size READ size WRITE setSize RESET resetSize NOTIFY sizeChanged)
    private: QSize m_size;
    public: QSize size() const;
    Q_SLOT TestClass &setSize(const QSize &v);
    Q_SLOT void resetSize();
    Q_SIGNAL void sizeChanged(QSize &);

    //Auto-generated property id : uint
    Q_PROPERTY(uint id READ id CONSTANT)
    private: uint m_id;
    public: uint id() const;

    //Auto-generated property name : QString
    Q_PROPERTY(QString name READ name WRITE setName RESET resetName NOTIFY nameChanged)
    private: QString m_name;
    public: QString name() const;
    Q_SLOT TestClass &setName(const QString &v);
    Q_SLOT void resetName();
    Q_SIGNAL void nameChanged(QString &);

    //Auto-generated property real : qreal
    Q_PROPERTY(qreal real READ real WRITE setReal RESET resetReal NOTIFY realChanged DESIGNABLE false SCRIPTABLE false)
    private: qreal m_real;
    public: qreal real() const;
    Q_SLOT TestClass &setReal(const qreal &v);
    Q_SLOT void resetReal();
    Q_SIGNAL void realChanged(qreal);

    // source
    int TestClass::number() const {
    return m_number;
    }

    TestClass &TestClass::setNumber(const int &v) {
    if (m_number != v) {
    m_number = v;
    emit numberChanged(m_number);
    }
    return *this;
    }

    int TestClass::resetNumber() {
    //TODO reset
    }

    QColor TestClass::color() const {
    return m_color;
    }

    TestClass &TestClass::setColor(const QColor &v) {
    if (m_color != v) {
    m_color = v;
    emit colorChanged(m_color);
    }
    return *this;
    }

    QColor TestClass::resetColor() {
    //TODO reset
    }

    QSize TestClass::size() const {
    return m_size;
    }

    TestClass &TestClass::setSize(const QSize &v) {
    if (m_size != v) {
    m_size = v;
    emit sizeChanged(m_size);
    }
    return *this;
    }

    QSize TestClass::resetSize() {
    //TODO reset
    }

    uint TestClass::id() const {
    return m_id;
    }

    QString TestClass::name() const {
    return m_name;
    }

    TestClass &TestClass::setName(const QString &v) {
    if (m_name != v) {
    m_name = v;
    emit nameChanged(m_name);
    }
    return *this;
    }

    QString TestClass::resetName() {
    //TODO reset
    }

    qreal TestClass::real() const {
    return m_real;
    }

    TestClass &TestClass::setReal(const qreal &v) {
    if (m_real != v) {
    m_real = v;
    emit realChanged(m_real);
    }
    return *this;
    }

    qreal TestClass::resetReal() {
    //TODO reset
    }

    @



  • Removed a few bugs I discovered while using the generator.

    Also found this in the doc:

    bq. The READ function is const and returns the property type. The WRITE function returns void and has exactly one parameter of the property type. The meta-object compiler enforces these requirements.

    which got me thinking chaining won't work, but after a quick test it does seem to work properly.



  • Minor fixes:

    • no private member is generated for non-STORED properties

    • WRITE and NOTIFY is disabled for CONSTANT properties


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.