Pull to refresh

Comments 12

Начните уже использовать теги

<source lang="cpp"> //Для C++
<source lang="javascript"> // Для QML


Читать же невозможно.

много статей на тему QML, но все они оставляют за кадром некоторые моменты.


Какие именно моменты вы осветили, которых нету в других статьях?

На мой взгляд это очередной стопицотый пост про qml для самых маленьких.
А теперь, когда код оформлен, конструктивная критика:
1. Для Q_PROPERTY setter должен быть объявлен как public slot, иначе из того же QML нельзя будет например написать:
myObject.myProperty = 10


2. Changed сигнал должен emit'иться не абы где, а именно в setter'е и, желательно, только в том случае, если пришедшее значение действительно отличается от текущего.

3. Q_INVOKABLE относится не к группе методов, а к каждому конкретному методу, поэтому есть смысл писать его на одной строчке с объявлением метода.

4. Менять значение переменной использующейся в Q_PROPERTY напрямую — моветон, а вас же есть setter.

5. Ну и в общем Qt Creator умеет сам генерировать идейно правильный код для setter & getter если поставить курсор на слово Q_PROPERTY и нажать Alt+Enter
1. Для Q_PROPERTY setter должен быть объявлен как public slot, иначе из того же QML нельзя будет например написать:
это неправда
А доказать?
Не, я, конечно, согласен это может быть и private slot, но это должен быть слот или Q_INVOKABLE.
Запустите и проверьте, setter должен просто быть public, и ему не надо быть слотом или invokable
Проверил, признаю, был не прав, moc уже на основе Q_PROPERTY генерирует код:
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< int*>(_v) = a(); break;
        }
        _id -= 1;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setA(*reinterpret_cast< int*>(_v)); break;
        }
        _id -= 1;
Ну да, просто Вы же могли раньше(до QML) объявлять property с методами-не-слотами. QML просто использует существующую инфраструктуру, а не вводит дополнительные ограничения(за исключением NOTIFY)
1. Для Q_PROPERTY setter должен быть объявлен как public slot, иначе из того же QML нельзя будет например написать:
myObject.myProperty = 10

private:
    int someProperty;

и
myObject.myProperty = 10

Взаимоисключающие параграфы, ведь.
А для случая с public свойством, вы абсолютно правы, сеттер обязательно должен быть слотом либо Q_INVOKABLE

5. Ну и в общем Qt Creator умеет сам генерировать идейно правильный код для setter & getter если поставить курсор на слово Q_PROPERTY и нажать Alt+Enter

А за это огромное спасибо, не знал о такой возможности, очень удобно.
Взаимоисключающие параграфы

Что Вы этим хотели сказать? С чего вдруг они взаимоисключающие?
А для случая с public свойством, вы абсолютно правы, сеттер обязательно должен быть слотом либо Q_INVOKABLE

Нет он не прав, и Вы, как следствие, тоже.
Вот вам кусок кода из Qt, дабы поставить точку:

class Q_AUTOTEST_EXPORT QDeclarativeBorderImage : public QDeclarativeImageBase
{
    Q_OBJECT
    Q_ENUMS(TileMode)

    Q_PROPERTY(QDeclarativeScaleGrid *border READ border CONSTANT)
    Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged)
    Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)

public:
    QDeclarativeBorderImage(QDeclarativeItem *parent=0);
    ~QDeclarativeBorderImage();

    QDeclarativeScaleGrid *border();

    enum TileMode { Stretch = Qt::StretchTile, Repeat = Qt::RepeatTile, Round = Qt::RoundTile };

    TileMode horizontalTileMode() const;
    void setHorizontalTileMode(TileMode);
Что Вы этим хотели сказать? С чего вдруг они взаимоисключающие?

С того что нечего пытаться изменять private свойство извне без прямого вызова сеттера.

И покажите тогда уже и qml файл где horizontalTileMode используется для записи.
Это не private свойство, private только поле в котором хранится значение. Вообще сложно представить private свойство мне, могу представить read-only — когда не объявлен сеттре, но оно от этого private'ом не становится.

Про public slot я был не прав смотрите ответ выше.
Вы не верно интерпретируете приватность. Если Вы объявили Q_PROPERTY, то это, априори, публичное свойство. Нет такого понятие как private property, Вы можете принять некое соглашение, что считать internal и external(в qml internal свойства де факто имеют префикс __, хотя никакого стандарта на это нет). C++, же, backends(т.е. то, что хранит состояние свойства) как правило находятся в private секции, этого требует инкапсуляция.
И покажите тогда уже и qml файл где horizontalTileMode используется для записи.

Целью моего комментария была восполнить пробел в Ваших знаниях, а не в собственных. Будьте добры, убедитесь в этом самостоятельно. Это больше Вам нужно, чем мне.
Sign up to leave a comment.

Articles