Question

I am writing an info-screen program. I created a full-screen widget and draw contents onto it.

In order to extend the life cycle of the TFT-display device, I want to implement a pixel-shifting feature. With other words, in every X minutes, I shift the screen to left/right/top/down for Y pixels.

My approach is as follows:

  1. I use two layers (two QWidget).
  2. I paint contents on the top layer.
  3. When a pixel-shifting is performed, I just move the top layer for specified offset.
  4. And then fill a background color to the bottom layer.

However, I found a problem:

If I move up the top layer for 10 pixels, the 10-pixel-content goes out of the screen. But when I move this layer down for 10 pixels. The 10-pixel-content will not be updated, it is gone.

How can I keep these 10-pixel-content? Is there any magic widget flag to solve this problem?

UPDATE 1: The code is written in language D, but it is easy to understand:

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);
Was it helpful?

Solution

Looking at the code, my first guess is that your region might be wrong. Try repainting the whole widget each time, and see if that solves the missing 10 pixel problem. If it does, then try working out why your region isn't covering the newly exposed portion.

One possibility along those lines: I notice in your Screen::requestForPaint method that you directly call the Canvas::requestForPaint without doing anything with the region. In Qt, the coordinates for anything like that are often assumed to be local, so if you don't account for the current position of the canvas widget, you might get an incorrect region.

OTHER TIPS

Why not setting the position of the widget directly...? Another options might be using QPainter::translate(-1,-1) or something similar.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top