Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > рисование с помощью QPainter в QPixmap


Автор: olegkuzn 15.11.2013, 10:57
Вот код программы :
Код

#include "ImgLabel.h"
#include <QMouseEvent>
#include <QPainter>

// ImgLabel - класс производный от QLabel
void ImgLabel::mousePressEvent(QMouseEvent *ev)
{
    if(ev->buttons() | Qt::LeftButton)
    {
        QPixmap* pixDraw = (QPixmap*)pixmap();            // pixDraw - картинка из QLabel
        if(pixDraw == 0)return;

        m_ppaintDraw = new QPainter(pixDraw);             // создаем контекст устройства
        m_ppixmapTmp = new QPixmap(m_rectDraw.size());    // создаем объект QPixmap для сохранения "закрашеной" области

        m_rectDraw.moveCenter(ev->pos());                 // перемещаем прямоугольник в центр мыши

        *m_ppixmapTmp = pixDraw->copy(m_rectDraw);        // запоминаем выбранную область
        m_ppaintDraw->fillRect(m_rectDraw,                // ставит "белую пелену" в  область прямоугольника
                               QColor(255,255,255,128));
        update(m_rectDraw);                               // перерисовываем элемент
    }
}

void ImgLabel::mouseMoveEvent(QMouseEvent *ev)
{
    if(ev->buttons() | Qt::LeftButton)
    {
        if(m_ppaintDraw == 0) return;

        m_ppaintDraw->drawPixmap( m_rectDraw, *m_ppixmapTmp);           // восстанавливаем сохраненную картинку
        update(m_rectDraw);                                             // обновляем экран

        m_rectDraw.moveCenter(ev->pos());                                            // перемещаемся на новое место

        *m_ppixmapTmp = pixmap()->copy(m_rectDraw);                     // запоминаем картину

        m_ppaintDraw->fillRect(m_rectDraw, QColor(255,255,255,128));    // создаем "белую пелену"

        update(m_rectDraw);                                             // перерисовываем картинку
    }
}

void ImgLabel::mouseReleaseEvent(QMouseEvent *ev)
{
    if(ev->buttons() | Qt::LeftButton)
    {
        if(m_ppaintDraw)
        {
            m_ppaintDraw->drawPixmap( m_rectDraw, *m_ppixmapTmp);       // восстанавливаем сохраненную картинку
            update(m_rectDraw);

            delete m_ppixmapTmp;                                        // удаляем объект QPixmap
            m_ppixmapTmp = 0;

            delete m_ppaintDraw;                                        // удаляем контекст устройства
            m_ppaintDraw = 0;
        }
    }
}



Код делает то что нужно - При нажатии левой кнопки мыши появляется прямоугольник из "белой пелены" и
перемещается по экрану вслед за мышью. Однако при движении мыши справа налево остается шлейф из вертикальных линий "белой пелены". Это глюк Qt или я что-то сделал не так.

Автор: vinter 15.11.2013, 11:29
Вообще говоря, такие вещи делаются под другому. В мышиных функциях запоминаются координаты, а потом вызывается update(). И всё рисование идёт в paintEvent(), в котором запомненные координаты превращаются в тот рисунок, который необходим. Размазывать рисование по обработчикам мыши не лучший выбор. 

Автор: olegkuzn 15.11.2013, 13:56
m_ppaintDraw используется для объекта QPixmap а не для текущего виджета. update() перерисует всю картинку, а желательно перерисовать только измененную часть картинки.

Автор: vinter 15.11.2013, 14:59
Для части картинки есть update(const QRect & rect). Так или иначе, тебе нужно стирать старый Pixmap и рисовать новый. Проще всего это делается полной перерисовкой.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)