Russian Qt Forum
Ноябрь 25, 2024, 02:11 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Как рисовать не в paintEvent?  (Прочитано 22755 раз)
marty
Гость
« : Июль 15, 2009, 17:14 »

 Здравствуйте!
 Собственно сабж, и возможнро ли это?

 Хочу рисовать (дорисовывать) изображение/его части, реагируя на действия пользователя - мышь, клавиатура, при этом не хотелось бы самому заводить QPixmap, в который будет производится отрисовка, и который будет копироваться в widget по paintEvent'у.
 Хочу так:
1) Создаем Qpixmap размером с виджет.
2) копируем в него изображение виджета (или только его части), планируется использовать hint о том, какая область будет обновляться
3) Рисуем на QPixmap'е
4) Копируем QPixmap или его часть на виджет.

 Не пойму, как реализовать пп 2, 4? Нашел вроде метод grabWidget, но как я понял, он вызывает событие paintEvent для виджета, чего как раз хочется избежать.

Записан
f-r-o-s-t
Гость
« Ответ #1 : Июль 15, 2009, 17:31 »

Мало понятно чего ты хочешь, подробней можно зачем оно тебе
как рисовать первое что нашел в Assistent это Plug & Paint Example
Записан
marty
Гость
« Ответ #2 : Июль 15, 2009, 18:01 »

 Я хочу модифицировать изображение на виджете по различным событиям - так, пример, на котором я пытаюсь добиться нужного мне поведения, по движению мышки печатает в углу ее координаты.
 Что я не хочу - не хочу заводить pixmap, на котором все будет рисоваться, для последующей переброски на экран по paintEvent (так сделано в Plug & Paint); не хочу запоминать данные и потом учитывать при перерисовке по paintEvent.
 Backbuffer pixmap я не хочу заводить - тогда для каждого класса виджета, который хочет рисовать не только по paintEvent, я должен наследоваться не от QWidget, а от моего класса, в котором этот бэкбуфер реализован.
 Запоминать данные и потом делать update - перерисовка виджетов может быть длительной, и поэтому не хочется все перерисовывать.
 В принципе, если ничего другого не остается, то наверно так и сделаю. Тогда вопрос возникает, по каким событиям следует изменять размеры беэкбуфера? И второй возникающий вопрос - QPainter (или QWidget) вроде реализует двойную буфферизацию, если я сам буду буфер использовать, как отключить стандартную?
Записан
f-r-o-s-t
Гость
« Ответ #3 : Июль 15, 2009, 18:15 »

А какой нибудь пример кроме мышки, подробнее что должно быть в конце.
отключить буферезацию QWidget::setAttribute(Qt::WA_PaintOnScreen).
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #4 : Июль 15, 2009, 18:44 »

marty может проще рисовать повех виджета, как здесь, задачка изначальная была другая, но на основе неё можно сделать.
Записан

Юра.
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #5 : Июль 15, 2009, 18:53 »

Вот ещё: Рисование_поверх_дочерних_виджетов
Записан

Юра.
marty
Гость
« Ответ #6 : Июль 15, 2009, 20:31 »

А какой нибудь пример кроме мышки, подробнее что должно быть в конце.
отключить буферезацию QWidget::setAttribute(Qt::WA_PaintOnScreen).

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

 Написал такой класс:
Код:
template <typename T>
class QOffscreenDraw : public T
{
    QPixmap backBuffer;
    bool    bOnlyCopyBackBuffer;

public:

   QOffscreenDraw(QWidget * parent = 0, Qt::WindowFlags f = 0)
       : T(parent, f)
       , backBuffer()
       , bOnlyCopyBackBuffer(false)
       {
        backBuffer = QPixmap ( width(), height() );
         /* T:: */ setAttribute(Qt::WA_PaintOnScreen);
       }

    QPixmap* getOffscreenBuffer()
       {
        return &backBuffer; // QPainter(&backBuffer);
       }

    void updateFromBackBuffer()
       {
        bOnlyCopyBackBuffer = true;
        repaint();
        bOnlyCopyBackBuffer = false;
       }

protected:

    virtual void doPaint( QPainter *painter, QPaintEvent *event )
       {}

    void resizeEvent( QResizeEvent * event )
       {
        T::resizeEvent(event);
        if (!event->isAccepted()) return;
        backBuffer = QPixmap( event->size() );
       }

    void paintEvent(QPaintEvent *event)
       {
        if (!bOnlyCopyBackBuffer)
           {
            QPainter painter(&backBuffer);
            doPaint( &painter, event );
           }

        QPainter thisPainter(this);
        thisPainter.drawPixmap( QRect( 0, 0, width(), height()), backBuffer, QRect( 0, 0, width(), height()) );
       }
};


class RenderArea : QOffscreenDraw<QWidget>


« Последнее редактирование: Июль 15, 2009, 20:41 от marty » Записан
marty
Гость
« Ответ #7 : Июль 15, 2009, 20:38 »

Что-то редактор сообщений стало колбасить, не смог дописать
Код:
// испорльзовать так
class RenderArea : QOffscreenDraw<QWidget>
{
    // переопределяем для рисования всей картинки целиком
    void doPaint( QPainter *painter, QPaintEvent *event );
};

// Если нужно асинхронно (не в paintEvente) порисовать, делаем так
{
 ...
    { // QPainter заключили в отдельную область видимости, чтоб он разрушился перед копированием картинки,
      // можно сделать p.end();
     QPainter p(renderArea->getOffscreenBuffer());
     // рисуем
    }
    renderArea->updateFromBackBuffer();
}


« Последнее редактирование: Июль 15, 2009, 20:40 от marty » Записан
marty
Гость
« Ответ #8 : Июль 15, 2009, 20:43 »

 А вообще, что-то Qt не такая уж хорошая, раз для такого простого действия надо так извращаться.
Записан
Rcus
Гость
« Ответ #9 : Июль 15, 2009, 21:14 »

Точно, не бери Qt, жизнь себе поломаешь! ©
Такие заявления мне кажутся забавными, особенно на фоне серьезных обсуждений багов и недостатков архитектуры Qt Улыбающийся
« Последнее редактирование: Июль 15, 2009, 21:17 от Rcus » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #10 : Июль 15, 2009, 21:27 »

>>Точно, не бери Qt, жизнь себе поломаешь! ©
Плюс милиён, говно этот Qt, надо на Визуал Басике, тем более, что там уже всё за тебя сделано.
Записан

Юра.
marty
Гость
« Ответ #11 : Июль 16, 2009, 01:32 »

Точно, не бери Qt, жизнь себе поломаешь! ©
Такие заявления мне кажутся забавными, особенно на фоне серьезных обсуждений багов и недостатков архитектуры Qt Улыбающийся
Что в этом заявлении кажется вам забавным? По-моему, данное ограничение по рисованию только во время paintEvent довольно большой недостаток, которого нет у WinAPI (и его оберток) и у wxWidgets.
Записан
marty
Гость
« Ответ #12 : Июль 16, 2009, 01:35 »

>>Точно, не бери Qt, жизнь себе поломаешь! ©
Плюс милиён, говно этот Qt, надо на Визуал Басике, тем более, что там уже всё за тебя сделано.
Я бы с удовольствием, но надо на плюсах, да так, чтоб работало с WTL, wxWidgets да с Qt. С последним постоянно какой-то гемморой возникает, в отличии от первых двух библиотек.
 Вы бы лучше приведенный код попинали, вместо ёрничания.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #13 : Июль 16, 2009, 01:42 »

Продолжать сравнение Qt лучше здесь
Записан

Юра.
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #14 : Июль 16, 2009, 01:44 »

>>Вы бы лучше приведенный код попинали, вместо ёрничания.
ну я тебе ссылки давал, во втрой ссылке  как раз расматривается вопрос рисования не в paintEvent
Записан

Юра.
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.101 секунд. Запросов: 22.