Почему QWidget::paintEvent не вызывается?

У меня есть простая иерархия виджетов: GraphWidget -> MotionWidget -> NodeWidget. Я новичок в Qt, поэтому пока не совсем уверен в том, как работают некоторые внутренности. По сути, GraphWidget создает один виджет MotionWidget M и устанавливает родительский элемент M в себя. Затем M уходит и создает группу NodeWidgets. Однако NodeWidgets никогда не рисуются, и их функция paintEvent() не вызывается.

Я попытался создать MotionWidget напрямую, без GraphWidget, и все работает. Так почему же все ломается, если я добавляю GraphWidget в иерархию?

Вот вставка с соответствующими фрагментами кода из моего проекта. Я также включил вывод GraphWidget::dumpObjectTree() вверху.

Изменить: забыл включить ссылку для вставки;) http://rafb.net/p/Zp39CF94.html< /а>

Обновление: я завернул MotionWidget в макет.

До:

GraphWidget :: GraphWidget( QWidget *parent ) : QWidget( parent )
{
    setFixedSize( 500, 500 );

    MotionWidget *n = new MotionWidget( 5, this );
}

После

GraphWidget :: GraphWidget( QWidget *parent ) : QWidget( parent )
{
    setFixedSize( 500, 500 );

    QVBoxLayout *l = new QVBoxLayout;

    MotionWidget *n = new MotionWidget( 5 );

    l->addWidget( n );

    setLayout( l );
}

Теперь последний работает. т.е. все рисуется. Тогда возникает вопрос... Почему? Почему в первом случае не сработало, а во втором сработало?


person sneg    schedule 12.03.2009    source источник
comment
Устранит ли размещение this->setGeometry(parent->rect()) в конструкторе MotionWidget необходимость в другом макете? Что, если вы вызовете n->show() после его создания?   -  person Judge Maygarden    schedule 12.03.2009


Ответы (1)


Я не согласен с ответом Айуа. Передача родителя объекту добавит дочерний элемент в визуальную иерархию. (В противном случае использование Designer для создания виджета, включающего другие, но с абсолютным позиционированием, не сработает.) Однако, вероятно, были другие факторы, препятствующие рисованию.

Из-за того, что макет заставил все работать, я предполагаю, что в обеих версиях MotionWidget не имеет заданного размера. Это будет означать, что в первом примере он будет иметь размер 0x0 пикселей, который Qt оптимизирует при попытке рисования. Во втором примере макет управляет размером добавляемых к нему виджетов, поэтому он увеличивает MotionWidget и, таким образом, снова начинает получать события рисования.

Чтобы исправить это, вы можете установить размер явно, как вы делаете для GraphWidget, или вы можете сделать некоторые динамические размеры на основе размера родителя, или GraphWidget может управлять размером, или любой из большого количества различных параметров. Макеты тоже могут быть хороши, но не являются обязательными.

person Caleb Huitt - cjhuitt    schedule 13.03.2009
comment
Вы совершенно правы. Извините за мой плохой ответ. Я никогда не использую абсолютное позиционирование, поэтому я забыл, что в этом случае он использует родительский виджет для визуальной иерархии. - person Aiua; 19.03.2009