QGraphicsItem封装的直线控件(添加箭头)
最近在封装QGraphicsScene的很多控件,需要在绘制直线后,显⽰箭头表⽰⽅向,并且该直线的起点和终点可变化(箭头需要实时变化)
qreal alph = atan2(m_pointF2.y()-m_pointF1.y(), m_pointF2.x()-m_pointF1.x());
此情可待中文歌词
painter->translate(m_pointF2);
qreal angle = (alph*180)/3.14159;
qDebug()<<angle;
painter->rotate(angle);
狼爪冲锋衣怎么样painter->drawLine(QPointF(-10,-5),QPointF(0,0));
painter->drawLine(QPointF(-10,+5),QPointF(0,0));
在paint()函数中,进⾏重绘的封装的时候,添加代码。
在⽹上找的都是各种计算⾓度,其实将箭头所在的点作为画笔的起点,然后计算出直线的⾓度,再将画笔的⾓度设置为和直线的⾓度⼀致即可。
源码:
.cpp
#include "visionlineitem.h"
#include <QDebug>
#include <QPainterPath>
#include "../control/color.h"
VisionLineItem::VisionLineItem(bool bEdit, QPointF p1, QPointF p2, qreal penWidth, bool color_enable, QColor borderColor, QColor lectedColor, QColor brushColor, VisionItem *parent) : VisionItem(parent)
{
if(color_enable){
m_borderColor = borderColor;
}el{
m_borderColor = borderColor;
}
m_brushColor = brushColor;
m_lectedColor = lectedColor;
m_pointF1 = p1;m_pointF2 = p2;
m_penColor = borderColor;
m_penWidth = penWidth;
m_bEdit = bEdit;
m_type = ItemType::Paint_Line;
m_type = ItemType::Paint_Line;
if(m_bEdit){
tSelectedStatus(true);
}el{
tSelectedStatus(fal);
}
m_miniRect1 = new MiniRect(m_pointF1.x()-5,m_pointF1.y()-5,10,10,m_borderColor,m_lectedColor,m_brushColor,this); // m_miniRect1->tGlobleData(this->scene()->views().at(0)->matrix().m22(),g_penWidth);
m_miniRect1->tIndex(1);
connect(m_miniRect1,SIGNAL(signalIndex(int)),this,SLOT(slotMiniRectIndex(int)));
m_miniRect1->hide();
m_miniRect2 = new MiniRect(m_pointF2.x()-5,m_pointF2.y()-5,10,10,m_borderColor,m_lectedColor,m_brushColor,this); // m_miniRect2->tGlobleData(this->scene()->views().at(0)->matrix().m22(),g_penWidth);
m_miniRect2->tIndex(2);
connect(m_miniRect2,SIGNAL(signalIndex(int)),this,SLOT(slotMiniRectIndex(int)));
m_miniRect2->hide();
updateRect(m_pointF1,m_pointF2);
}
void VisionLineItem::tLine(QPointF p1, QPointF p2)
{
m_pointF1 = p1;
m_pointF2 = p2;
m_miniRect1->tRect(m_pointF1.x()-5,m_pointF1.y()-5,10,10);
m_miniRect2->tRect(m_pointF2.x()-5,m_pointF2.y()-5,10,10);
updateRect(m_pointF1,m_pointF2);
}
void VisionLineItem::tPenWidth(qreal penWidth)
{
m_penWidth = penWidth;
}
void VisionLineItem::tPenColor(QColor color)
{
m_penColor = color;
}
bool VisionLineItem::getPosInArea(qreal x, qreal y)
{
qreal A = m_pointF2.y() - m_pointF1.y();
qreal B = m_pointF1.x() - m_pointF2.x();
qreal C = m_pointF2.x()*m_pointF1.y() - m_pointF1.x()*m_pointF2.y();
qreal l = fabs(A*x + B*y + C)/sqrt(A*A+B*B);
if( l < 5 || this->cursor().shape() == Qt::SizeAllCursor){
return true;
枯藤老树昏鸦小桥流水人家}el{
return fal;
}
}
QVector<QPointF> VisionLineItem::getPoints(){
QVector<QPointF> vec_p;
vec_p.append(m_pointF1);
vec_p.append(m_pointF2);
青山冈昌return vec_p;
}
QRectF VisionLineItem::boundingRect() const
{
if(this->scene()->views().at(0)->matrix().m22() > 1){
if(this->scene()->views().at(0)->matrix().m22() > 1){
return QRectF(m_x-5*(1/this->scene()->views().at(0)->matrix().m22()),m_y-5*(1/this->scene()->views().at(0)->matrix().m22()),m_width+10*(1/this->sc ene()->views().at(0)->matrix().m22()),m_height+10*(1/this->scene()->views().at(0)->matrix().m22()));
}el{
return QRectF(m_x-5*(1/this->scene()->views().at(0)->matrix().m22()),m_y-5*(1/this->scene()->views().at(0)->matrix().m22()),m_width+10*(1/this->sc ene()->views().at(0)->matrix().m22()),m_height+10*(1/this->scene()->views().at(0)->matrix().m22()));
}
}
void VisionLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(widget)
Q_UNUSED(option)
painter->tRenderHint(QPainter::Antialiasing, true);
if(option->state & QStyle::State_Selected){
painter->tPen(QPen(QBrush(m_lectedColor),g_penWidth*(1/this->scene()->views().at(0)->matrix().m22())));
}el{
painter->tPen(QPen(QBrush(m_borderColor),g_penWidth*(1/this->scene()->views().at(0)->matrix().m22())));
}
painter->drawLine(m_pointF1,m_pointF2);
//绘制箭头
qreal alph = atan2(m_pointF2.y()-m_pointF1.y(), m_pointF2.x()-m_pointF1.x());
painter->translate(m_pointF2);
qreal angle = (alph*180)/3.14159;
qreal len = 5*(1/this->scene()->views().at(0)->matrix().m22());
// qDebug()<<angle;
painter->rotate(angle);
painter->drawLine(QPointF(-(2*len),-len),QPointF(0,0));
painter->drawLine(QPointF(-(2*len),+len),QPointF(0,0));
if(!m_bEdit)
return;
//绘制编辑框
if(option->state & QStyle::State_Selected){
m_miniRect1->show();
m_miniRect2->show();罗织构陷
m_bSelected = true;
tSelectedStatus(m_bSelected);
}el{
m_miniRect1->hide();
m_miniRect2->hide();
m_bSelected = fal;
tSelectedStatus(m_bSelected);
}
}
void VisionLineItem::mouPressEvent(QGraphicsSceneMouEvent *event)
{
if(!m_bEdit)
return;
// A = Y2 - Y1
// B = X1 - X2
// C = X2*Y1 - X1*Y2
QGraphicsItem::mouPressEvent(event);
if(m_iIndex != -1)
return;
qreal A = m_pointF2.y() - m_pointF1.y();
qreal B = m_pointF1.x() - m_pointF2.x();
qreal C = m_pointF2.x()*m_pointF1.y() - m_pointF1.x()*m_pointF2.y();
m_lastPointF = event->scenePos();
qreal l = fabs(A*event->scenePos().x() + B*event->scenePos().y() + C)/sqrt(A*A+B*B);
qDebug()<<"l:: "<<l<<A<<B<<C;
if(l < 5 || this->cursor().shape() == Qt::SizeAllCursor){
qDebug()<<"in area";
tSelectedStatus(true);
}el{
qDebug()<<"out area";
tSelectedStatus(fal);
}
this->scene()->update();
}
void VisionLineItem::mouMoveEvent(QGraphicsSceneMouEvent *event)
{
if(!m_bEdit)
return;
if(!m_bSelected)
return;
// QGraphicsItem::mouMoveEvent(event);
QPointF disPointF = event->scenePos()-m_lastPointF;
m_lastPointF = event->scenePos();
if(m_iIndex == 1){
m_pointF1 = event->scenePos();
}el if(m_iIndex == 2){
m_pointF2 = event->scenePos();
}el{
//移动整体
m_pointF1 = m_pointF1 + disPointF;
m_pointF2 = m_pointF2 + disPointF;
}
updateRect(m_pointF1,m_pointF2);
emit signalChanged(this);
this->scene()->update();
}
void VisionLineItem::mouReleaEvent(QGraphicsSceneMouEvent *event)
{
《氓》
if(!m_bEdit)
return;
if(m_iIndex != -1)
return;
qreal A = m_pointF2.y() - m_pointF1.y();
qreal B = m_pointF1.x() - m_pointF2.x();
qreal C = m_pointF2.x()*m_pointF1.y() - m_pointF1.x()*m_pointF2.y();
qreal l = fabs(A*event->scenePos().x() + B*event->scenePos().y() + C)/sqrt(A*A+B*B); if( l < 5 || this->cursor().shape() == Qt::SizeAllCursor){
emit signal_clicked(this,true,true,event->scenePos().x(),event->scenePos().y());
低血压怎么调理
QGraphicsItem::mouReleaEvent(event);
轻视}el{
emit signal_clicked(this,true,fal,event->scenePos().x(),event->scenePos().y()); return;
return;
}
}
void VisionLineItem::updateRect(QPointF p1, QPointF p2)
{
if(p1.x() < p2.x()){
m_x = p1.x();
}el{
m_x = p2.x();
}
if(p1.y() < p2.y()){
m_y = p1.y();
}el{
m_y = p2.y();
}
m_width = fabs(p1.x()-p2.x());
m_height = fabs(p1.y()-p2.y());
m_miniRect1->tPos(m_pointF1.x()-5,m_pointF1.y()-5);
m_miniRect2->tPos(m_pointF2.x()-5,m_pointF2.y()-5);
}
void VisionLineItem::slotMiniRectIndex(int index)
{
if(index == 1){
//移动点1
m_iIndex = 1;
this->scene()->views().at(0)->tCursor(Qt::SizeAllCursor);
}el if(index == 2){
//移动点2
m_iIndex = 2;
this->scene()->views().at(0)->tCursor(Qt::SizeAllCursor);
}el{
//恢复正常
m_iIndex = -1;
this->scene()->views().at(0)->tCursor(viewCursor);
}
}
.h
/****************************************************************************
** @brief line类
** @note 可编辑的line,绘制完成后,可修改线的起点和终点,带有箭头的表⽰⽅向,默认起点指向终点** @date create:2018-09-28
** @example
****************************************************************************/
#ifndef VISIONLINEITEM_H
#define VISIONLINEITEM_H
#include <QObject>
#include <QPainter>
#include "../control/visionitem.h"
#include "../control/minirect.h"
class VISIONGRAPHSHARED_EXPORT VisionLineItem : public VisionItem
{
Q_OBJECT
public: