一、前言
在Qt的圖形視圖架構中,QGraphicsScent提供了
items()
來擷取場景中的圖元集合,提供了
selectedItems()
來擷取場景中被選中的圖元集合,擷取集合之後,通過
qgraphicsitem_cast<>()
就可以将QGraphicsItem轉換為相應的子類,例如:
if (isItemSelected(LineElementItem::Type)) {
LineElementItem* item = qgraphicsitem_cast<LineElementItem*>(selectedItems().first());
//操作item
}
但是實際在使用QWT時,并沒有這麼多的API來供開發者使用。
二、具體流程
1、定義圖元辨別
在QGraphicsItem中,采用
Type
來辨別圖元類别:
class TextItem : public QGraphicsTextItem {
Q_OBJECT
public:
enum { Type = UserType + TYPE_TEXT };
TextItem(QGraphicsItem* parent = 0);
int type() const
{
return Type;
}
};
而在QWT中,則采用
rtti
來辨別圖元類别:

class QwtTextLabel : public QwtPlotItem
{
public:
QwtTextLabel();
virtual int rtti() const //指定目前圖元項代表的意義
{
return QwtPlotItem::Rtti_PlotUserItem + textLabel_item;
}
}
通過QWT源碼可知,QwtPlotItem将
QwtPlotItem::Rtti_PlotUserItem(枚舉值為100)
之後的用于使用者自定義圖元辨別,是以我們隻需要在這個基礎上定義自己的圖元辨別即可;
自定義QWT圖元類
#ifndef QWTVALUELINE_H
#define QWTVALUELINE_H
#include <qwt_plot_item.h>
#include <qwt_painter.h>
#include "DataDefine.h"
class QPainter;
class QPen;
class QFont;
class QwtScaleMap;
class QwtScaleDiv;
class QwtValueLine : public QwtPlotItem
{
public:
QwtValueLine();
QPointF ValueLine_Pos1;
QPointF ValueLine_Pos2;
QColor ValueLine_Color;
virtual int rtti() const; //指定目前圖元項代表的意義
virtual void draw( QPainter *p,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
const QRectF &rect ) const; //自定義圖元項繪制函數
void set_ValueLine_Pos1(QPointF);
void set_ValueLine_Pos2(QPointF);
void set_ValueLine_Color(QColor);
};
#endif // QWTVALUELINE_H
#include "qwtvalueline.h"
QwtValueLine::QwtValueLine()
{
ValueLine_Pos1 = QPointF(-1,-1);
ValueLine_Pos2 = QPointF(-1,-1);
ValueLine_Color = QColor(255,0,0);
}
int QwtValueLine::rtti() const //虛函數,指定目前圖元項代表的意義
{
return QwtPlotItem::Rtti_PlotUserItem + valueLine_item;
}
void QwtValueLine::draw( QPainter *p,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
const QRectF &rect ) const //純虛函數,自定義圖元項繪制函數
{
p->setRenderHints(QPainter::Antialiasing, true); //設定反鋸齒
p->setPen(QPen(ValueLine_Color,3));
QwtPainter::drawLine(p,ValueLine_Pos1,ValueLine_Pos2);
}
void QwtValueLine::set_ValueLine_Pos1(QPointF pos1)
{
this->ValueLine_Pos1 = pos1;
this->itemChanged();
}
void QwtValueLine::set_ValueLine_Pos2(QPointF pos2)
{
this->ValueLine_Pos2 = pos2;
this->itemChanged();
}
void QwtValueLine::set_ValueLine_Color(QColor color)
{
this->ValueLine_Color = color;
this->itemChanged();
}
void PlotView::mousePressEvent(QMouseEvent *event)
{
mousePressed = event->pos(); //實體坐标
isSelected_valueLine = false;
for(int i=0; i<this->itemList().size(); ++i) {
if(this->itemList().at(i)->rtti() == QwtPlotItem::Rtti_PlotUserItem + valueLine_item) {
valueLine = (QwtValueLine*)this->itemList()[i]; //将QwtPlotItem類轉換為自定義圖元類QwtValueLine
//valueLine = dynamic_cast<QwtValueLine*>(this->itemList()[i]);
}
}
if(valueLine != nullptr) {
if(qAbs(mousePressed.x() - valueLine->ValueLine_Pos1.x()) <= 10) {
isSelected_valueLine = true;
}
}
}