перемещение дочернего виджета внутри родительского виджета без перерисовки - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь выровнять дочерний виджет по правому нижнему углу родительского виджета.Перекрашивание дочернего виджета стоит дорого, поэтому я хочу избежать этого.Поскольку я перемещаю только дочерний виджет со статическим содержимым, теоретически перекрашивание не требуется.Но я не знаю, как этого добиться.Я реагирую на resizeEvent(), в котором я обновляю позицию ребенка до угла.Я установил атрибуты виджета (метод пробной ошибки), чтобы минимизировать события рисования, насколько я мог.Но все еще есть некоторые события перерисовки, которые требуются для ребенка, когда размер родительского элемента изменяется - когда он также увеличивается или уменьшается.При изменении размера медленно и только в одном направлении (x или y) кажется, что полоса шириной всего в 1 пиксель перекрашивается.При изменении размеров быстрее и в обоих направлениях одновременно, дочерний виджет перекрашивается все.Можно ли настроить код, чтобы избежать перекраски дочернего виджета полностью?Я бы не хотел писать ручной алгоритм двойной буферизации для этого случая сам, я надеюсь, что Qt сможет решить это как-нибудь для меня.Это так?

#include <QApplication>
#include <QDebug>
#include <QPainter>
#include <QPaintEvent>
#include <QWidget>

class ChildWidget : public QWidget
{
public:
    ChildWidget(QWidget *parent) : QWidget(parent)
    {
        setAttribute(Qt::WA_StaticContents);
        setAttribute(Qt::WA_OpaquePaintEvent);
    }

protected:
    void paintEvent(QPaintEvent *event) override
    {
        qDebug() << "paintEvent" << event->rect();
        QPainter painter(this);
        painter.fillRect(event->rect(), QBrush(QColor("red")));
    }
};

class ParentWidget : public QWidget
{
public:
    ParentWidget()
    {
        m_childWidget = new ChildWidget(this);
        m_childWidget->resize(100, 100);
        setAttribute(Qt::WA_StaticContents);
        resize(200, 200);
    }

protected:
    void resizeEvent(QResizeEvent *event) override
    {
        QWidget::resizeEvent(event);
        m_childWidget->move(width() - 100, height() - 100);
    }

private:
    ChildWidget *m_childWidget;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ParentWidget w;
    w.show();

    return a.exec();
}

Примечание. В моем последнем случае использования этот родительский виджет должен быть полностью покрыт несколькими непересекающимися дочерними виджетами, и каждый из этих дочерних виджетов будет непрозрачным и позаботится окрасит всю свою площадь.Т.е. никакой специальной обработки альфа-канала не требуется.Это может быть важной информацией для установки атрибутов виджета.

Примечание: я попробовал хитрость, не перемещая потомка сразу, а отложил его с помощью QTimer::singleShot(0, [this]{m_childWidget->move(width() - 100, height() - 100);}); Это предотвращает перекрашивание во время изменения размера родительского виджета, но только в случаях, когда размер родителя увеличивается.Когда он сжимается, он такой же, как и раньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...