Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Система рисования. Печать _ Отрисовка линий по нажатию кнопки мыши

Автор: myr 29.9.2009, 14:50

Здраствуйте. Посоветуйте. Ничего не знаю но сделать надо.
Выделить область окна по нажатию кнопки мышки. Мышкой щелкнули - потянулась линия, второй раз одна сохранилась вторая от нее началась, как измерение маршрута в топ плане.
после полного выделения все стереть.

Надо при обработке mouse event, вызывать paint? как сохранить преведущую линию между отрисовками? как все стереть потом?

Или отошлите на пример.
Спасибо.


Автор: kwisp 29.9.2009, 15:02

мало что понял из вопроса.

П.С.
ключи для поиска в ассисетенте и на форуме
paintEvent
qpainter
mouseEvent

Автор: myr 29.9.2009, 15:13

Есть изображение.
Щелкнули мышкой. При перемешении курсора и нажатой кнопке мыши тянется линия. Одним концом линия закреплена на месте нажатия кнопки мыши. Перемещаетьс туда, куда двигаеться курсор.
Не понимаю как ее отрисовывать и стирать.

Автор: kwisp 29.9.2009, 15:52

переопределяешь paintEvent в классе наследнике от QPaintDevice(QWidget, QImage, QPixmap etc.) в нем же заводишь член класса -- координата последнего нажатия мыши(может список координат нажатий при рисовании ломанной линии) в переопределенном paintEvent рисуешь линию от сохранненой координаты до текущего положения мыши, в событии движения мыши mouseMove вызываешь update().
основная идея такая.

Автор: myr 29.9.2009, 20:59

Спасибо. Понятно.
Как удалить нарисованную линию? После отрисовки всего полинома?. Отрисовали пользователь посмотрел - стал рисовать нову старая затерлась.
Или сама пропадет?
Есть какие-то механизмы?


Автор: kwisp 30.9.2009, 8:03

ну как сказать.
если хранить координаты концов линий к примеру в векторе и перерисовывать все линии в paintEvent, то удалив из вектора координату при следующей перерисовке не нужной линии не будет.(если удалить все то ничего не будет)

читай про рисование в Qt, обнаружишь что перед вызовом paintEvent виджет уже стёрт. т.е. если в нем вызвать paintEvent предка то все линии пропадут.
флагами можно выставлять условия в переопределенном paintEvent рисовать или не рисовать(вызывать отрисовку вектора или просто вызывать paintEvent родительского класса).

Автор: kwisp 30.9.2009, 9:03

вот тебе кусок кода
разбирайся.

Раскрывающийся текст

#ifndef __MOUSELINE_H__
#define __MOUSELINE_H__
#include <QWidget>
#include <QVector>
#include <QPoint>
#include <QPainter>
#include <QBrush>
#include <QPen>
#include <QPaintEvent>

class MouseLine: public QWidget {
    public:
        MouseLine(QWidget* p = 0): QWidget(p)
        {

        }
    private:
        QVector<QPoint>        m_points;

    protected:
        void paintEvent(QPaintEvent* ev)
        {
            if(m_points.isEmpty()) QWidget::paintEvent(ev);
            else if(m_points.size() > 1){
                QPainter painter(this);
                painter.setPen(Qt::red);
                QVectorIterator<QPoint> iter(m_points);
                QPoint begin,end;
                end  = iter.next();
                while(iter.hasNext()){
                    begin = end;
                    end = iter.next();
                    painter.drawLine(begin,end);
                }
//                painter.drawLines(m_points);
//                painter.drawLines(m_points.data() + 1, m_points.size()/2 - 1);
            }
        }
        void mousePressEvent(QMouseEvent* ev)
        {
            Qt::MouseButton button = ev->button();
            const QPoint& point = ev->pos();
            if(button == Qt::LeftButton) m_points.append(point);
            else if(button == Qt::RightButton) m_points.clear();
            update();
        }
        void mouseMoveEvent(QMouseEvent* ev)
        {
            m_points.last() = ev->pos();
            update();
        }

};


#endif


Автор: myr 30.9.2009, 12:58

Спасибо. Пробую.

Автор: myr 30.9.2009, 19:40

Алгоритм понятен, получилось.
Проконсультируйте еще пожалуйста.
У меня главное окно программы на нем компоненнт, наследуемый от Scrollview, у компонента есть сигнал после отрисовки.
SignalAfterPaint(QPainter* p, int cx, int cy, int cw, int ch);
По событию мыши главного окна вызываю для Scrollview -repaint() не попадаю в SignalAfterPaint
Если вызываю contextUpdate() все работает, но жутко мигает. В Scrollview у меня графика с мелкими элементами, перерисовывать не желательно.
Возникло 2 вопроса.
- как достучаться до paintEvent компонента, кооторый уже лежит на форме. (Не понимаю. по шагам если можно.)
- как нарисовать поверх? не периресовывая всего изображения в Scrollview



Автор: kwisp 30.9.2009, 20:35

Цитата(myr @ 30.9.2009, 20:40) *
- как достучаться до paintEvent компонента, кооторый уже лежит на форме. (Не понимаю. по шагам если можно.)
- как нарисовать поверх? не периресовывая всего изображения в Scrollview

есть соответствующие темы на форуме.
сейчас буду вспоминать где они и как называются а ты поищи.

отвечу сразу на первый вопрос сразу
-- никак, только наследовать компонент и переопределять.

Автор: myr 30.9.2009, 22:43

С миганем ушло, если в contextUpdate() правильную область передавать. Но теперь все падает с закрыванием Х ов, видимо сообщения repaint копяться в очереди, надо их сбрасывать где-то. После update вызвать processEvents ()


Читаю. QPaintEvent, installEventFilter, QPainter, Overpainting http://www.forum.crossplatform.ru/index.php?showtopic=2839

Автор: kwisp 30.9.2009, 22:53

myr,
а почему вызываешь именно repaint()
попробуй update()


Автор: myr 30.9.2009, 23:26

Все рисует. Если erase в update в false, лучше. Не все события update обрабатываються. Но думаю проблемы в медленной виртуальной машине.
Получаеться в paintEvent можно попасть только в формах нарисованных вручную.

Автор: Litkevich Yuriy 1.10.2009, 6:05

Цитата(myr @ 1.10.2009, 3:26) *
Не все события update обрабатываються.
это-то и хорошо, очередь сообщений не переполняется

Автор: kwisp 1.10.2009, 8:10

Цитата(myr @ 1.10.2009, 0:26) *
Получаеться в paintEvent можно попасть только в формах нарисованных вручную.

почему же?
не обязатльно.
можешь унаследоваться создать свой класс, а в дизайнере указать хедер и предка и дизайнер воткнет тебе твой один рукописный виджет. поэтому можешь комбинировать на форме свои и стандартные виджеты.
правой кнопкой по виджету promoted widgets... дальше поймешь.
либо если прочёл в этой теме
http://www.forum.crossplatform.ru/index.php?showtopic=2839
всё то поймешь как рисовать на дочерних окнах и виджетах.

Автор: myr 1.10.2009, 16:21

По теме.
За пример спасибо.
чтоб не мигало передаю область, размеры которой обновляю (расширяю) в зависимост от координат;
с update сильнее мигает. и если update посылать из pressMouse не все линии отрисовываються они оптимизируються.
Решено это где писать?

Автор: kwisp 1.10.2009, 16:25

Цитата(myr @ 1.10.2009, 17:21) *
Решено это где писать?

не понятно :(

Автор: myr 1.10.2009, 16:42

здесь нет сорри.
(отметить тему решено)

Автор: Litkevich Yuriy 1.10.2009, 16:52

myr, можешь переименовать тему.

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)