代码之家  ›  专栏  ›  技术社区  ›  HiFile.app - best file manager

在父控件内移动子控件而不重新绘制

  •  0
  • HiFile.app - best file manager  · 技术社区  · 6 年前

    resizeEvent() ,其中我将孩子的位置更新到角落。我已经设置了widget属性(trial error method),以尽可能减少绘制事件。但是,在调整父对象的大小时(也包括放大和收缩时),仍有一些为子对象调用的重绘事件。当缓慢调整大小并且只在一个方向(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();
    }
    

    注意:在我的最后一个用例中,这个父小部件将被几个不重叠的子部件完全覆盖,并且每个子部件都是不透明的,并且将负责绘制其整个区域。一、 e.不需要对α通道进行特殊处理。这可能是设置小部件属性的重要信息。

    注意:我试过一个把戏,不是马上把孩子搬走,而是用 QTimer::singleShot(0, [this]{m_childWidget->move(width() - 100, height() - 100);}); 这可以防止在父窗口小部件调整大小时重新绘制,但仅在父窗口大小增大的情况下。当它收缩时,它和以前一样。

    0 回复  |  直到 6 年前