Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: KontAr от Декабрь 15, 2011, 15:53



Название: подскажите как...
Отправлено: KontAr от Декабрь 15, 2011, 15:53
... реализовать перемещение view над сценой при помощи нажатой правой кнопкой мыши? Функция должна работать только тогда, когда размер сцены больше вью.


Название: Re: подскажите как...
Отправлено: _OLEGator_ от Декабрь 15, 2011, 16:13
Код
C++ (Qt)
void QGraphicsView::setDragMode(DragMode mode)


Название: Re: подскажите как...
Отправлено: KontAr от Декабрь 15, 2011, 18:58
не тащит. даже в ассистенте ничего понять не могу (пример с мышами). Можно еще одну подсказку?


Название: Re: подскажите как...
Отправлено: _OLEGator_ от Декабрь 15, 2011, 19:58
Подсказка №2
Код
C++ (Qt)
void QGraphicsView::setDragMode(QGraphicsView::ScrollHandDrag);
%QTDIR%\examples\graphicsview\collidingmice


Название: Re: подскажите как...
Отправлено: popper от Декабрь 15, 2011, 20:14
уточни задачу. наверное, нужно перетаскивать видимую область сцены вслед за движением мыши при нажатой правой кнопке, типа как в Adobe Reader с левой кнопкой?


Название: Re: подскажите как...
Отправлено: KontAr от Декабрь 15, 2011, 20:19
подсказка №2 не сработало, я так и делал.

да, именно как в ридере


Название: Re: подскажите как...
Отправлено: KontAr от Декабрь 15, 2011, 20:24
во вью в mousePressEvente я указал setDragMode(QGraphicsView::ScrollHandDrag), а в mouseReleaseEvent вернул как было. что еще нужно сделать?


Название: Re: подскажите как...
Отправлено: _OLEGator_ от Декабрь 15, 2011, 21:44
Да, извиняюсь, не досмотрел, что правая кнопка нужна.
Видимо придется реализовывать самому, раз такой функционал нужен.


Название: Re: подскажите как...
Отправлено: KontAr от Декабрь 16, 2011, 14:57
ну нато так нато. за какой параметр вью цепляться? так вроде нет типа viewRect(QrectF *)


Название: Re: подскажите как...
Отправлено: _OLEGator_ от Декабрь 16, 2011, 15:07
Можно использовать
Код
C++ (Qt)
void QGraphicsView::ensureVisible ( const QRectF & rect, int xmargin = 50, int ymargin = 50 )


Название: Re: подскажите как...
Отправлено: popper от Декабрь 16, 2011, 21:12
Сейчас не могу посмотреть, как я делал перетаскивание, но точно использовал в переопределенном методе QGraphicsView::mouseMoveEvent функцию
Код:
void QGraphicsView::centerOn ( const QPointF & pos )
а pos рассчитывал по смещению курсора мыши


Название: Re: подскажите как...
Отправлено: KontAr от Декабрь 17, 2011, 08:57
нужно же сначала узнать, какие координаты сцены отображаются? или узнавать центр вью?


Название: Re: подскажите как...
Отправлено: popper от Декабрь 17, 2011, 15:46
центр view
Код:
QGraphicsView::rect().center()
переводим в координаты сцены
Код:
QGraphicsView::mapToScene


Название: Re: подскажите как...
Отправлено: KontAr от Декабрь 18, 2011, 09:22
ерунда какая-то: в mouseMoveEvente команда
Код:
centerOn(mapToScene(rect().center());
не должна что-либо изменять, а область просмотра убегает в правый нижний угол (0 у меня слева внизу). Из-за чего это?


Название: Re: подскажите как...
Отправлено: popper от Декабрь 18, 2011, 20:42

попробуй манипулировать с центром прямоугольника сцены
Код:
 QGraphicsScene::sceneRect
и использовать
Код:
QGraphicsView::mapFromScene


Название: Re: подскажите как...
Отправлено: KontAr от Декабрь 21, 2011, 17:05
что то не получается:
Код:
void GraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if(midButtonIsPressed)
    {
        QPointF p = mapToScene(event->pos()) - startPoint;
        centerOn(mapToScene(rect().center()) + p);

        startPoint = mapToScene(event->pos());
        return;
    }
}

уже нервов нехватает...


Название: Re: подскажите как...
Отправлено: popper от Декабрь 22, 2011, 09:59
Я ошибся сказав, что использовал centerOn.
Вот работающий код:
Код:
void GeoMapGraphicsView::mousePressEvent ( QMouseEvent * e )
{
    if (e->button() == Qt::RightButton){
        this->setCursor(Qt::ClosedHandCursor);
        isTouched = true;
        startMousePos = this->mapToScene(e->pos());
        e->accept();
    }
    else e->ignore();
}

void GeoMapGraphicsView::mouseReleaseEvent ( QMouseEvent * e )
{
    if (e->button() == Qt::RightButton && isTouched){
        setCursor(Qt::OpenHandCursor);
        isTouched = false;
        e->accept();
    }
    else e->ignore();
}

void GeoMapGraphicsView::mouseMoveEvent ( QMouseEvent * e )
{
    QPointF curMousePos = this->mapToScene(e->pos());
    if ((e->buttons() & Qt::RightButton) && isTouched)
        translate(curMousePos.x() - startMousePos.x(), curMousePos.y() - startMousePos.y());
    else
        QToolTip::showText(e->globalPos(),
                           QString("%1 %2").arg(curMousePos.x()).arg(90.0-curMousePos.y()),
                           this, QRect());
    e->accept();
}


Название: Re: подскажите как...
Отправлено: GreatSnake от Декабрь 22, 2011, 11:57
Я ошибся сказав, что использовал centerOn.
Вот работающий код:
Некоторые поправки:
1. В mousePressEvent() вставить проверку:
Код
C++ (Qt)
if( verticalScrollBar()->isVisible() || horizontalScrollBar()->isVisible() ) ...
 
2. Зачем в mouseMoveEvent() использовать довольно-таки тяжелый translate(), когда можно просто двигать вьюпорт так:
Код
C++ (Qt)
horizontalScrollBar()->setValue( horizontalScrollBar()->value() + (...) );
verticalScrollBar()->setValue( verticalScrollBar()->value() + (...) );
3. Наверное в mousePressEvent() и mouseReleaseEvent() нужно не игнорировать событие, а вызывать соответствующий метод базового класса.


Название: Re: подскажите как...
Отправлено: popper от Декабрь 22, 2011, 15:40
1. Согласен, для задачи топикстартера это нужно.
2. Сравнивая перемещение вью с помощью реализованного метода мыши и с помощью скроллов, которые тоже перемещаю мышью, не заметил существенной разности. Тут нужно тестировать.
3. Согласен


Название: Re: подскажите как...
Отправлено: KontAr от Январь 10, 2012, 20:17
почему то translate не работает. может флаг какой поставить надо?