Qt нарисованный контент теряется - PullRequest
2 голосов
/ 15 января 2010

Я пишу информационную программу. Я создал полноэкранный виджет и нарисую на нем содержимое.

Чтобы продлить жизненный цикл устройства TFT-дисплея, я хочу реализовать функцию сдвига пикселей. Другими словами, каждые X минуты я сдвигаю экран влево / вправо / вверх / вниз для Y пикселей.

Мой подход заключается в следующем:

  1. Я использую два слоя (два QWidget).
  2. Я рисую содержимое на верхнем слое.
  3. Когда выполняется сдвиг пикселей, я просто перемещаю верхний слой для указанного смещения.
  4. А затем залейте фоновым цветом нижний слой.

Однако я обнаружил проблему:

Если я переместюсь вверх по верхнему слою на 10 пикселей, 10-пиксельное содержимое исчезнет с экрана. Но когда я перемещаю этот слой вниз на 10 пикселей. 10-пиксельное содержимое не будет обновлено, оно пропало.

Как мне сохранить этот 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);

Ответы [ 2 ]

2 голосов
/ 17 января 2010

Глядя на код, я думаю, что ваш регион может быть неправильным. Попробуйте перекрасить весь виджет каждый раз, и посмотрите, решит ли это проблему с отсутствующими 10 пикселями Если это так, попробуйте выяснить, почему ваш регион не покрывает недавно открытую часть.

Одна возможность в том же духе: в вашем методе Screen::requestForPaint я заметил, что вы напрямую вызываете Canvas::requestForPaint, ничего не делая с регионом. В Qt координаты для чего-либо подобного часто считаются локальными, поэтому, если вы не учитываете текущую позицию виджета canvas, вы можете получить неправильный регион.

1 голос
/ 17 января 2010

Почему бы не установить положение виджета напрямую ...? Другие варианты могут использовать QPainter :: translate (-1, -1) или что-то подобное.

...