16,816
社区成员




想实现类似matplotlib工具栏功能,点击按钮可切换功能模式。但现在对于平移和拖拽框缩放这两个功能不知道如何整合到QChartView上
这是关于平移的代码
#include "chartview.h"
#include <QValueAxis>
#include <QApplication>
ChartView::ChartView(QWidget* parent)
: QChartView{ parent }
, prevPoint_{}
, leftButtonPressed_{}
, ctrlPressed_{}
, alreadySaveRange_{}
, xRange_{}
, yRange_{}
, coordItem_{}
{
//设置橡皮筋拖动模式
setDragMode(QGraphicsView::RubberBandDrag);
//关闭鼠标跟踪
setMouseTracking(false);
}
ChartView::ChartView(QChart *chart, QWidget *parent)
: ChartView{ parent } // C++11 Delegating constructors
{
setChart(chart);
}
ChartView::~ChartView()
{
}
void ChartView::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
if(m_isMoving){
prevPoint_ = event->pos();
leftButtonPressed_ = true;
}
}
}
void ChartView::mouseMoveEvent(QMouseEvent *event)
{
if(m_isMoving){
//创建文本
if (!coordItem_) {
coordItem_ = new QGraphicsSimpleTextItem{ chart() };
coordItem_->setZValue(5);
coordItem_->setPos(100, 60);
coordItem_->show();
}
const QPoint curPos{ event->pos() };
//将获取到的点进行准换为可带有小数位的坐标系点位
const QPointF curVal{ chart()->mapToValue(QPointF(curPos)) };
coordItem_->setText(QString("X = %1, Y = %2").arg(curVal.x()).arg(curVal.y()));
if (leftButtonPressed_) {
const auto offset = curPos - prevPoint_;
prevPoint_ = curPos;
if (!alreadySaveRange_) {
saveAxisRange();
alreadySaveRange_ = true;
}
chart()->scroll(-offset.x(), offset.y());
}
}
else if(m_isTouching){
return;
}
}
void ChartView::mouseReleaseEvent(QMouseEvent *event)
{
leftButtonPressed_ = false;
if (event->button() == Qt::RightButton) {
if (alreadySaveRange_) {
chart()->axisX()->setRange(xRange_[0], xRange_[1]);
chart()->axisY()->setRange(yRange_[0], yRange_[1]);
}
}
}
void ChartView::wheelEvent(QWheelEvent *event)
{
#if (QT_VERSION <= QT_VERSION_CHECK(6,0,0))
const auto pos = QPointF(event->pos());
const auto isZoomIn = event->delta() > 0;
#else
const auto pos = event->position();
const auto isZoomIn = event->angleDelta().y() > 0;
#endif
const QPointF curVal = chart()->mapToValue(pos);
if (!alreadySaveRange_) {
saveAxisRange();
alreadySaveRange_ = true;
}
auto zoom = [](QValueAxis* axis, double centre, bool zoomIn) {
constexpr auto scaling{ 1.5 };
const double down = axis->min();
const double up = axis->max();
double downOffset{};
double upOffset{};
if (zoomIn) {
downOffset = (centre - down) / scaling;
upOffset = (up - centre) / scaling;
}
else {
downOffset = (centre - down) * scaling;
upOffset = (up - centre) * scaling;
}
axis->setRange(centre - downOffset, centre + upOffset);
};
if (ctrlPressed_) {
auto axis = qobject_cast<QValueAxis*>(chart()->axisY());
zoom(axis, curVal.y(), isZoomIn);
} else {
auto axis = qobject_cast<QValueAxis*>(chart()->axisX());
zoom(axis, curVal.x(), isZoomIn);
}
}
void ChartView::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Control)
ctrlPressed_ = true;
}
void ChartView::keyReleaseEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Control)
ctrlPressed_ = false;
}
void ChartView::saveAxisRange()
{
const auto axisX = qobject_cast<QValueAxis*>(chart()->axisX());
xRange_ = { axisX->min(), axisX->max() };
const auto axisY = qobject_cast<QValueAxis*>(chart()->axisY());
yRange_ = { axisY->min(), axisY->max() };
}
这是拖拽框缩放的代码
#include "chartview.h"
#include <QMouseEvent>
#include <QValueAxis>
ChartView::ChartView(QWidget *parent)
: QChartView(parent)
{
setRubberBand(QChartView::RectangleRubberBand);
}
ChartView::ChartView(QChart *chart, QWidget *parent)
: QChartView(chart, parent)
{
setRubberBand(QChartView::RectangleRubberBand);
}
bool ChartView::viewportEvent(QEvent *event)
{
if (event->type() == QEvent::TouchBegin and m_enableTouchInitialization) {
// By default touch events are converted to mouse events. So
// after this event we will get a mouse event also but we want
// to handle touch events as gestures only. So we need this safeguard
// to block mouse events that are actually generated from touch.
m_isTouching = true;
// Turn off animations when handling gestures they
// will only slow us down.
chart()->setAnimationOptions(QChart::NoAnimation);
}
return QChartView::viewportEvent(event);
}
void ChartView::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
if (m_isTouching){
return;
}
}
QChartView::mousePressEvent(event);
}
void ChartView::mouseMoveEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
if (m_isTouching){
return;
}
}
QChartView::mouseMoveEvent(event);
}
void ChartView::mouseReleaseEvent(QMouseEvent *event)
{
buttonPress=false;
if (m_isTouching)
m_isTouching = false;
if (m_isMoving)
m_isMoving = false;
chart()->setAnimationOptions(QChart::SeriesAnimations);
QChartView::mouseReleaseEvent(event);
}
//![1]
void ChartView::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_Plus:
chart()->zoomIn();
break;
case Qt::Key_Minus:
chart()->zoomOut();
break;
//![1]
default:
QGraphicsView::keyPressEvent(event);
break;
}
}
###########################################
setRubberBand(QChartView::NoRubberBand);
setDragMode(QGraphicsView::RubberBandDrag);
###########################################
setRubberBand(QChartView::RectangleRubberBand);
setDragMode(QGraphicsView::NoDrag);
初步想法是设置模式,通过切换模式来实现不同功能,但不起作用,现在初始化为拖拽框缩放功能,点击切换后平移功能无法实现,现在不知道如何能将上述两种功能整合到一块,实现功能切换。
希望大佬们能给予一些建议,感谢各位了!
自绘是早晚要学会的技能