如何强制重新绘制 QWidget?

问题描述 投票:0回答:1

给出以下主窗口实现:

#include <QApplication>

#include "MainWindow.h"

namespace ui {
MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        child(this) {
    this->resize(425, 450);
    this->child.move(10, 10);
    this->child.resize(400, 400);
}

MainWindow::~MainWindow() {}

void MainWindow::showEvent(QShowEvent* event) {
    QWidget::showEvent(event);

    qDebug() << "Updating.";
    this->child.update();
    this->child.update();
    this->child.update();
    this->child.update();
    this->child.repaint();
    this->child.repaint();
    this->child.repaint();
    this->child.repaint();
    QApplication::processEvents();
} 
}  // namespace ui

以及看起来像这样的小部件:

#include <QPainter>

#include "Widget.h"

namespace ui {
Widget::Widget(QWidget *parent) :
        QWidget(parent) { }

void Widget::paintEvent(QPaintEvent *event) {
    qDebug() << "paintEvent called.";
    QWidget::paintEvent(event);
}
}  // namespace ui

我希望看到至少四个(可能超过八个)“paintEvent 被调用”。控制台中的消息。然而,控制台只显示:

Updating.
paintEvent called.
paintEvent called.

如果我删除 this->child.update() 中的所有

this->child.repaint()
MainWindow.cpp
调用,则输出
完全相同

如果

update()
repaint()
实际上没有更新或重新绘制小部件,我应该做什么才能强制重绘小部件?

c++ qt qwidget qt6
1个回答
0
投票

Qt 期望你的

paintEvent()
方法是幂等的——也就是说,调用它的次数应该没有任何区别,因为给定相同的小部件状态,它应该始终将相同的图形图像绘制到小部件的屏幕区域上.

因此,期望的是,只要发生可能需要修改小部件外观的更改,您的代码就会调用

update()
,并且 Qt 将确保在那之后尽快调用
paintEvent()
,最好只调用一次。

您永远不需要明确调用

repaint()

你没有这么明确地说,但我的蜘蛛意识告诉我,你可能正在尝试解决一个问题,即在主/GUI线程内调用的函数需要很长时间才能返回,这会导致你的GUI没有及时更新。

如果是这种情况,那么正确的解决方案是要么使该例程返回得更快,要么(如果不可能)将其移至单独的线程中,以便它可以异步执行而不阻塞 GUI 线程当它运行时。 Qt 中主/GUI 线程调用的函数应始终快速返回,否则 GUI 更新将被推迟,导致糟糕的用户体验。

© www.soinside.com 2019 - 2024. All rights reserved.