我正在尝试使子窗口小部件与父窗口小部件的右下角对齐。子窗口小部件的重新绘制成本很高,因此我想避免这样做。因为我只移动具有静态内容的子窗口小部件,所以从理论上讲不需要重新绘制。但是我不知道如何实现这一目标。我对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();
}
注意:在我的最终用例中,该父窗口小部件旨在由几个不重叠的子窗口小部件完全覆盖,并且这些子窗口小部件中的每个子窗口将是不透明的,并将负责绘制整个区域。即无需对Alpha通道进行特殊处理。这对于设置窗口小部件属性可能是重要的信息。
注意:我尝试了一种技巧,不是立即移动子项,而是使用QTimer::singleShot(0, [this]{m_childWidget->move(width() - 100, height() - 100);});
来推迟子项,这可以防止在父级窗口小部件调整大小期间重新绘制,但仅在父级大小增大的情况下才可以。当它收缩时,它与以前相同。