07 March, 2013

Q_PROPERTY, Qt Designer, moc, uic, и нестандартно именованный setter

Вы когда нибудь-задумывались, что есть принципиальная разница используете ли вы стандартное именование сеттера для свойства (т. е. setter начинается с set и продолжается именем свойства с большой буквы) как например здесь:
    Q_PROPERTY(int foo READ foo WRITE setFoo)
И вариантом когда имя setter'a имеет произвольное написание? Ну например вот так:
    Q_PROPERTY(int foo READ foo WRITE InitFoo)
А различие есть!
В коде moc есть такой вот метод
    bool stdCppSet() const {
        QByteArray s("set");
        s += toupper(name[0]);
        s += name.mid(1);
        return (s == write);
    }
Этот метод вызывается для каждого Q_PROPERTY и, если он возвращает false, то выставленный по умолчанию в true флаг StdCppSet сбрасывается и уже сброшенный записывается в метаинформацию.

До тех пор, пока вы не сделали плагин для Qt Designer для своего виджета - разницы никакой нет. Но она сразу повляется в обратном случае, дело в том, что дизайнер также генерирует несколько разный xml в ui-файле в случае, если свойство имеет нестандартно поименованный setter  А именно к элементу property добавляется аттрибут stdset="0".

Теперь мы подошли к самому главному, почему это важно? А важно это потому что когда по ui-файлу пойдет uic, он обратит внимание на этот аттрибут и сгенерирует совершенно другой код.
Например, в случае стандартного setter'а код в методе setupUi(), будет выглядеть так:
    widget->setFoo(10);
А в случае нестандартного так:
    widget->setProperty("foo", QVariant(10));
А рассказывал я это все потому, что, если вдруг по каким-то причинам вам необходимо изменить в уже существующем коде стандартное имя setter'а на нестандартное, будьте внимательны и не забудьте обновить все ui-файлы, где это свойство использовано, иначе uic будет генерировать неверные файлы заголовков.

02 March, 2013

Qt Designer: Использование собственных виджетов в качестве Promoting Widgets

Продолжаем развлекаться с Qt Designer, на это раз мы поговорим про использование собственных виджетов в Promoting Widgets. Promoting Widgets позволяют использовать базовый класс для представления дочернего на форме, то есть если у вас есть какой-либо наследник скажем QLineEdit, но вы не хотите писать для него плагин (например потому что наследник не имеет никаких новых свойств, а просто имеет другой внешний вид), то вы можете просто в форме показанной слева, выбрать базовым классом QLineEdit а Promoted классом указать своего наследника.



Проблема, которую мы будем решать заключается в том, что нет [задокументированного] пути указать в качестве базового класса, свой виджет имеющий плагин для дизайнера.