Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Hrundel от Августа 22, 2016, 11:11



Название: [РЕШЕНО] Выделение QGraphicsPath с помощью метода shape
Отправлено: Hrundel от Августа 22, 2016, 11:11
Всем привет,

очень хочется получить выделение объекта как в Illusatrator. То есть наезд мыша на заливку или если быть точным внуть QGraphicsPath должен выделять Item в сцене.
Я так понял, что для реализации надо использовать shape, который возвращается в виде QPainterPath. Но честно сказать - пока не поймуть что именно я должен с ним делать?

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

Спасибо


Название: Re: Выделение QGraphicsPath с помощью метода shape
Отправлено: Hrundel от Августа 22, 2016, 14:13
Думал что проблему решил через метод intersects, который сообщает пересекается ли мыша с внутренней областью Item.
Ан нет. что-то там не срабатывает.

Код
C++ (Qt)
void Qcr::hoverMoveEvent(QGraphicsSceneHoverEvent* e)
{
QPainterPath path = shape();
 
QRect mouseRect( mapToItem(this, e->pos()).x(), mapToItem(this, e->pos()).y(), 1, 1);
 
if( path.intersects( mouseRect ) )
{
isHover_ = true;
}
else
{
isHover_ = false;
}
update();
}
 


Название: Re: Выделение QGraphicsPath с помощью метода shape
Отправлено: Old от Августа 22, 2016, 16:08
bool QPainterPath::contains(const QPointF &point) const


Название: Re: Выделение QGraphicsPath с помощью метода shape
Отправлено: Hrundel от Августа 22, 2016, 16:14
Пробовал. Тоже не хочет. Включает выделение на вхождении в BoundingRect. А мне надо чтобы все прозрачные области игнорировались. То есть чтобы типа маски что-то было.
Смотрел в сторону opaqueArea но она возвращает Path который вырезан из основного. То есть дырки. Тоже нужная вешь но сначала надо внешние прозрачные исключить.


Название: Re: Выделение QGraphicsPath с помощью метода shape
Отправлено: Old от Августа 22, 2016, 16:28
Код
C++ (Qt)
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QPainterPath>
 
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget( QWidget *parent = 0 );
 
protected:
virtual void paintEvent( QPaintEvent *ev ) override;
virtual void mousePressEvent( QMouseEvent *ev );
 
private:
QPainterPath m_path;
};
 
#endif // WIDGET_H
 

Код
C++ (Qt)
#include "widget.h"
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
 
Widget::Widget( QWidget *parent ) :
QWidget( parent )
{
m_path.addEllipse( QRectF( 0, 0, 100, 100 ) );
}
 
void Widget::paintEvent( QPaintEvent * )
{
QPainter p( this );
 
p.drawPath( m_path );
}
 
void Widget::mousePressEvent( QMouseEvent *ev )
{
qDebug() << m_path.contains( ev->pos() );
}
 

Внутри эллипса выводит true, вне - false.


Название: Re: Выделение QGraphicsPath с помощью метода shape
Отправлено: Hrundel от Августа 22, 2016, 16:36
Только что проверил тоже самое в сцене - не работает: выводит для всех true

Код
C++ (Qt)
void Qcr::hoverMoveEvent(QGraphicsSceneHoverEvent* e)
{
QPainterPath path = shape();
 
             qDebug() << path.contains( e->pos() );
}
 

Вот класс целиком:

Код
C++ (Qt)
#include "Qcr.h"
#include <QDebug>
 
Qcr::Qcr(QGraphicsItem* parent)
: QGraphicsObject()
, startAngle(0)
, sweepLength(0)
, isHover_(false)
{
setAcceptHoverEvents(true);
 
boundingRect_.setX(-50);
boundingRect_.setY(-50);
boundingRect_.setWidth(100);
boundingRect_.setHeight(100);
}
 
Qcr::~Qcr()
{
}
 
void Qcr::paint(QPainter * painter, const QStyleOptionGraphicsItem* option, QWidget * widget /*= 0 */)
{
QPen myPen;
 
QPointF center, startPoint;
 
if(isHover_)
{
painter->setBrush(QBrush(QColor(255, 0, 0)));
}
else
{
painter->setBrush(QBrush(QColor(0, 255, 0)));
}
 
QPainterPath myPath;
myPath.moveTo(0,0);
myPath.arcTo(boundingRect_, startAngle, sweepLength);
myPath.closeSubpath();
 
painter->setPen(myPen);
painter->drawPath(myPath);
}
 
void Qcr::hoverMoveEvent(QGraphicsSceneHoverEvent* e)
{
QPainterPath path = shape();
 
if( path.contains(  e->pos() ) )
{
isHover_ = true;
}
else
{
isHover_ = false;
}
update();
}
 
void Qcr::hoverLeaveEvent(QGraphicsSceneHoverEvent * event)
{
isHover_ = false;
update();
}
 
 
QRectF Qcr::boundingRect() const
{
return boundingRect
}
 
void Qcr::setStartAngleX(int x)
{
startAngle = x;
update();
}
 
void Qcr::setStartAngleY(int y)
{
sweepLength = y;
update();
}
 
void Qcr::setStartAngleW(int w)
{
qreal oldW = boundingRect_.width();
qreal oldH = boundingRect_.height();
 
boundingRect_.setX(-w/2);
boundingRect_.setWidth(w);
boundingRect_.setHeight( qreal(oldW/w) * oldH );
boundingRect_.setY(-boundingRect_.height()/2);
update();
}
 
void Qcr::setStartAngleH(int h)
{
boundingRect_.setY(-h/2);
boundingRect_.setHeight(h);
update();
}
 
 


Название: Re: Выделение QGraphicsPath с помощью метода shape
Отправлено: Old от Августа 22, 2016, 16:42
Так а где переопределенный метод shape? :)
В базовом исполнении он boundingRect использует.


Название: Re: Выделение QGraphicsPath с помощью метода shape
Отправлено: Hrundel от Августа 22, 2016, 16:45
Ох ёёёёёёё!  :D ;D ;D ;D
Дык шейп переопределять надо !!!!  ;D ;D ;D ;D
Ну тоды ой!

Спасибо Old!


Название: Re: Выделение QGraphicsPath с помощью метода shape
Отправлено: Hrundel от Августа 22, 2016, 16:54
Работает только шум  стоит!  ;D ;D ;D :) :) :)