03 October, 2013

Пишем Objective-C код прямо в Qt проекте, не выходя из Qt Creator

На примере обработчика глобальных горячих клавиш MacOSX

Иногда бывают случаи, когда необходимо добавить в программу платформо-зависимый код, и, если в Linux и Windows все стандартные заголовки являются C/C++ заголовками, то в среде MacOSX это Objective-C заголовки, и если их просто подключить в проект, вы получите тысячи и тысячи ошибок сборки, поэтому для MacOSX необходима возможность писать часть кода на Objective-C,  и такая возможность есть.

05 August, 2013

С++ задачка

Еще одна задача на тонкости C++,
что выведет этот код?

#include <QtDebug>

class A {
public:
    virtual void foo(int i = 1)
    {
        qDebug() << "A" << i;
    }
};

class B : public A {
public:
    virtual void foo(int i = 100) override
    {
        qDebug() << "B" << i;
    }
};

int main()
{
    A *b = new B();
    B *bb = dynamic_cast<B *>(b);
    b->foo();
    bb->foo();
    return 0;
}

Ответ внутри

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 классом указать своего наследника.



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

31 January, 2013

Qt Designer плагин для виджета содержащего контейнер

Иногда, довольно таки не часто, но приходится создавать для своих виджетов плагины для Qt Designer. В Assistant отлично расписанно, как создать типовой плагин, мало того Qt Creator имеет отличный wizard, который выполняет большую часть работы. НО... Иногда (совсем редко) случается так, что нужно создать не совсем стандартный плагин. Ниже я буду рассказывать о случае, когда нужен плагин для виджета содержащего внутри себя контейнер, например QFrame или любой другой. Причем необходимо, чтобы этот вложенный контейнер оставался функционален в Qt Designer, и в нем можно было по прежнему размещать другие виджеты. О тонкостях ниже.