Qt 绘制的内容丢失了

Posted

技术标签:

【中文标题】Qt 绘制的内容丢失了【英文标题】:Qt painted content goes lost 【发布时间】:2010-01-15 16:57:03 【问题描述】:

我正在编写一个信息屏幕程序。我创建了一个全屏小部件并在其上绘制内容。

为了延长 TFT 显示设备的生命周期,我想实现像素移位功能。换句话说,每 X 分钟,我将屏幕向左/右/上/下移动 Y 个像素。

我的做法如下:

    我使用了两层(两个 QWidget)。 我在顶层绘制内容。 当执行像素移动时,我只是将顶层移动到指定的偏移量。 然后在底层填充背景色。

但是,我发现了一个问题:

如果我将顶层向上移动 10 像素,则 10 像素的内容会离开屏幕。但是当我将此层向下移动 10 个像素时。 10-pixel-content 不会更新,没了。

如何保留这些 10 像素的内容?有没有神奇的小部件标志来解决这个问题?

更新 1: 代码是用D语言写的,但是很容易理解:

class Canvas: QWidget

    private QPixmap content;

    this(QWidget parent)
    
        super(parent);
        setAttribute(Qt.WA_OpaquePaintEvent, true);
    

    public void requestForPaint(QPixmap content, QRegion region)
    
        this.content = content;
        update(region);
    

    protected override void paintEvent(QPaintEvent event)
    
        if (this.content !is null)
        
            QPainter painter = new QPainter(this);
            painter.setClipping(event.region);
            painter.fillRect(event.region.boundingRect, new QColor(0, 0, 0));
            painter.drawPixmap(event.region.rect, this.content);
            this.content = null;
            painter.setClipping(false);
        
    


class Screen: QWidget

    private Canvas canvas;

    this()
    
        super(); // Top-Level widget
        setAutoFillBackground(True);
        this.canvas = new Canvas(this);
        showFullScreen();
    

    public void requestForPaint(QPixmap content, QRegion region)
    
        this.canvas.requestForPaint(content, region);
    

    private updateBackgroundColor(QColor backgroundColor)
    
        QPalette newPalette = palette();
        newPalette.setColor(backgroundRole(), backgroundColor);
        setPalette(newPalette);
    

    public shiftPixels(int dx, int dy)
    
        this.canvas.move(dx, dy);
        updateBackgroundColor(new QColor(0, 0, 0)); // Just a demo background color
    


Screen screen = new Screen;
screen.requestForPaint(some_content, some_region);
screen.shiftPixels(0, -10);
screen.shiftPixels(0, 10);

【问题讨论】:

你能发布一些重现问题的示例代码吗?我从未见过小部件在可见时无法重绘。 【参考方案1】:

查看代码,我的第一个猜测是您的区域可能是错误的。尝试每次重新绘制整个小部件,看看是否能解决丢失 10 像素的问题。如果是,请尝试找出您所在区域未覆盖新暴露部分的原因。

沿着这些思路的一种可能性:我注意到在您的 Screen::requestForPaint 方法中,您直接调用 Canvas::requestForPaint 而不对该区域进行任何操作。在 Qt 中,类似的坐标通常被假定为本地坐标,因此如果您不考虑画布小部件的当前位置,您可能会得到一个不正确的区域。

【讨论】:

我的应用程序全屏运行,没有连接鼠标和键盘。画布通常不会变脏。所以,我只需要确保新绘制的区域看起来不错。但是,如果画布变脏了,我就不可能重新绘制整个画布,因为我还没有保存有关如何绘制整个屏幕的信息。 (当然有一些方法可以保存屏幕内容)我只是想知道,当我将它移出屏幕然后将其移回时,QWidget 的内容会丢失。我正在寻找解决方案。 顺便说一句:我为什么不每次都绘制整个屏幕的原因是我在屏幕上有一些字幕文本。如果我在 20 毫秒内重新绘制所有内容,CPU 使用率会很高。【参考方案2】:

为什么不直接设置小部件的位置...?另一个选项可能是使用 QPainter::translate(-1,-1) 或类似的东西。

【讨论】:

你的意思是,我应该只使用一个画布而不是两个。我应该用 QPainter::translate(dx, dy) 打印内容吗?但这并不能解决我的问题。我可能会在左上角画一些内容。 30 秒后,我在右下角绘制了一些其他内容。休息区保持不变。再过 30 秒后,我想要移动整个画布。此时,最简单的方法就是移动小部件,不是吗?

以上是关于Qt 绘制的内容丢失了的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 setStyleSheet() 添加样式而不丢失 Qt 中的原始样式?

从 Qt4 移植到 Qt5 时 Ctrl+U 组合键丢失

在openGL中绘制点时丢失了一些点

Android:图层可绘制丢失信息

C++ Qt“转到插槽”丢失

Windows下使用命令行编译Qt项目(解决DLL丢失问题)