Я пытаюсь выровнять дочерний виджет по правому нижнему углу родительского виджета.Перекрашивание дочернего виджета стоит дорого, поэтому я хочу избежать этого.Поскольку я перемещаю только дочерний виджет со статическим содержимым, теоретически перекрашивание не требуется.Но я не знаю, как этого добиться.Я реагирую на 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);});
Это предотвращает перекрашивание во время изменения размера родительского виджета, но только в случаях, когда размер родителя увеличивается.Когда он сжимается, он такой же, как и раньше.