QChartView上建立曲线,可以任意增加曲线上的点,并且可以用鼠标拖拽曲线上的点,来改变曲线的函数
1、任意增加曲线上的点,来改变曲线函数
void CurveGuiClass::UpdateData() //增加数据点
{
m_datatemp = series->points();
m_point = (m_datatemp[1] + m_datatemp[2])/2;
m_datatemp.insert(2,QPointF(m_point));
series1->replace(m_datatemp);
series->replace(m_datatemp);
series2->replace(m_datatemp);
changeseries3();
}
void CurveGuiClass::changeseries3()
{
m_datatemp = series->points();
int num = m_datatemp.count();
for (int i = 2; i < num + 2; i = i + 2)
{
QPointF temp;
temp = QPointF(m_datatemp[i].x(), m_datatemp[i - 1].y());
m_datatemp.insert(i, temp);
}
series3->replace(m_datatemp);
}
2、通过鼠标任意拖拽曲线上的点,来改变曲线的函数
在ChartView函数内重写MouseEvent鼠标事件,使得鼠标移动到ChartView控件时,鼠标移动会触发事件
class MyChartView : public QChartView
{
Q_OBJECT
public:
explicit MyChartView(MyChart* chart, QWidget* parent = 0);
~MyChartView();
private:
MyChart* m_chart;
QPoint m_mousePos;
protected:
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event);
};
void MyChartView::mouseMoveEvent(QMouseEvent* event)
{
m_chart->handlePointMove(event->pos());
QChartView::mouseMoveEvent(event);
}
计算鼠标拖拉的位置与选中点位置的距离,如果拖拉的位置与鼠标选中点位置的距离大于原本选中点的位置与曲线上点的位置,则刷新曲线上该点的位置,否则拖拉无效
qreal MyChart::distance(const QPointF& p1, const QPointF& p2)
{
return qSqrt((p1.x() - p2.x()) * (p1.x() - p2.x())
+ (p1.y() - p2.y()) * (p1.y() - p2.y()));
}
在QChart中重写曲线,通过ChartView函数触发的鼠标事件来改变Qchart中的曲线函数
void Chart::handlePointMove(const QPoint &point)
{
if (m_clicked) {
//Map the point clicked from the ChartView
//to the area occupied by the chart.
QPoint mappedPoint = point;
mappedPoint.setX(point.x() - this->plotArea().x());
mappedPoint.setY(point.y() - this->plotArea().y());
//Get the x- and y axis to be able to convert the mapped
//coordinate point to the charts scale.
QAbstractAxis *axisx = axes(Qt::Horizontal).first();
QValueAxis *haxis = 0;
if (axisx->type() == QAbstractAxis::AxisTypeValue)
haxis = qobject_cast<QValueAxis *>(axisx);
QAbstractAxis *axisy = axes(Qt::Vertical).first();
QValueAxis *vaxis = 0;
if (axisy->type() == QAbstractAxis::AxisTypeValue)
vaxis = qobject_cast<QValueAxis *>(axisy);
if (haxis && vaxis) {
//Calculate the "unit" between points on the x
//y axis.
double xUnit = this->plotArea().width() / haxis->max();
double yUnit = this->plotArea().height() / vaxis->max();
//Convert the mappedPoint to the actual chart scale.
double x = mappedPoint.x() / xUnit;
double y = vaxis->max() - mappedPoint.y() / yUnit;
//Replace the old point with the new one.
m_series->replace(m_movingPoint, QPointF(x, y));
//Update the m_movingPoint so we are able to
//do the replace also during mousemoveEvent.
m_movingPoint.setX(x);
m_movingPoint.setY(y);
}
}
}
3、可以将曲线的点输出成Xml文件,并通过读取Xml文件来生成曲线Qt拖拽ss
bool CurveClass::InportData()
{
QString sExePath = QCoreApplication::applicationDirPath();
QString strFilePath;
strFilePath = QString("%1//curve.xml").arg(sExePath);
QFile* file = new QFile(strFilePath);
if (!file->open(QFile::ReadOnly | QFile::Text))
{
return false;
}
m_xmlRead.setDevice(file);
if (m_xmlRead.readNextStartElement())
{
QXmlStreamAttributes attributes = m_xmlRead.attributes();
//qDebug() << m_xmlRead.name();
if (m_xmlRead.name() == "cureve")
{
if (m_xmlRead.readNextStartElement())
{
if (m_xmlRead.name() == "series")
{
int i = 1;
while (m_xmlRead.readNextStartElement())
{
QString strData_x;
QString strData_y;
QString strElement;
strElement = m_xmlRead.name().toString();
if (strElement == "Point")
{
while (m_xmlRead.readNextStartElement())
{
strData_x = QString("Point_x%1").arg(i);
strData_y = QString("Point_y%1").arg(i);
strElement = m_xmlRead.name().toString();
if (strElement == strData_x)
{
x = m_xmlRead.readElementText().toDouble();
qDebug() << m_xmlRead.readElementText() << x;
}
else if (strElement == strData_y)
{
y = m_xmlRead.readElementText().toDouble();
if (strElement == "Point_y1")
{
data.append(QPointF(0, y));
}
qDebug() << m_xmlRead.readElementText() << y;
++i;
data.append(QPointF(x, y));
}
else
{
qDebug() << "Skip element " ;
m_xmlRead.skipCurrentElement();;
}
}
}
}
}
}
}
else
{
file->close();
return false;
}
}
}