2010-01-15 9 views
2

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

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

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

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

Тем не менее, я нашел проблему:

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

Как сохранить 10-пиксельный контент? Есть ли волшебный флаг виджета для решения этой проблемы?

UPDATE 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); 
+0

Можете ли вы опубликовать несколько примеров кода, который воспроизводит проблему? Я никогда не видел, чтобы виджет не перерисовывался, когда он становился видимым. –

ответ

2

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

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

+0

Мое приложение работает в полноэкранном режиме, без мыши не подключена клавиатура. Холст не будет нормально испачкаться. Поэтому я должен только убедиться, что недавно окрашенная область выглядит хорошо. Однако, если полотно становится грязным, я не могу перерисовать весь холст, потому что я не сохранил информацию о том, как весь экран должен быть нарисован. (Конечно, есть некоторые способы сохранить содержимое экрана) Я просто подумал, что содержимое QWidget пропадает, когда я вывожу его из экрана, а затем перемещаю его. И я ищу решение для этого. – stanleyxu2005

+0

BTW: Причина, почему я не рисую весь экран каждый раз, заключается в том, что на экране есть текст выделения. Если я перекрашу все в 20 мс, использование процессора будет высоким. – stanleyxu2005

1

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

+0

Ты имеешь в виду, я должен просто использовать один холст вместо двух. И я должен печатать контент с помощью QPainter :: translate (dx, dy)? Но это не решает мою проблему. Я мог бы нарисовать некоторое содержимое в левом верхнем углу. Через 30 секунд я рисую другое содержимое внизу справа. Остальная часть остается неизменной. Через 30 секунд я хочу, чтобы весь холст был сдвинут. В этот момент, таким образом, самый простой способ - просто переместить виджет, не так ли? – stanleyxu2005