Qt记录:QCustomPlot开启opengl的问题总结

一. 项目场景:

提示:这里简述项目相关背景:

目前我在使用QCustomPlot过程中,由于需要频繁添加数据并刷新图表,考虑还是开启opengl功能。但是在开启opengl之后,由于多图表显示以及自适应高分辨率的使用,导致出现了两个问题,记录如下。

1. 下载freeglut源码

freeglut官网下载地址

2. 编译freeglut源码

(1)创建build文件夹,来存放cmake编译之后产生的项目文件

在这里插入图片描述

(2) cmake编译

打开VsCode,打开源码文件,进入build文件夹,然后cmake
在这里插入图片描述
在build文件夹内生成sln项目文件
在这里插入图片描述

(3)我使用的是VS2019+v142工具集,选择ALL_BUILD,使用Debug和Release进行编译生成Debug和Release下的动态库文件。

在这里插入图片描述
生成的dll在bin文件夹中,生成的lib文件子啊lib文件夹内。
在这里插入图片描述

在这里插入图片描述

3. QCustomPlot添加OpenGl

# test.pro文件

QT      += printsupport opengl
DEFINES += QCUSTOMPLOT_USE_OPENGL

win32: LIBS += -L$$PWD/../../3rdparty/freeglut/ -lfreeglut -lfreeglut_static -lopengl32
INCLUDEPATH += $$PWD/../../3rdparty/freeglut
DEPENDPATH += $$PWD/../../3rdparty/freeglut
# test.cpp
# qcustomplot开启opengl

_plot->setOpenGl(true);

二. 问题描述

正常时的图片如下:
在这里插入图片描述

在开启opengl之后,出现了两个问题。
问题一: 当界面上有多张qcustomplot图表时,多张图表的刷新会出现混乱。
在这里插入图片描述

问题二: Qt开启高分辨率自适应策略时,QCustomPlot开启opengl之后,图表内的像素比例会出现问题,导致图表显示异常。
在这里插入图片描述


解决方案:

问题一:
那是因为在开启opengl之后,opengl内部的上下文出现紊乱导致的。在qcustomplot.cpp内找到这个函数,添加下面代码即可。

#  qcustomplot.cpp

void QCPPaintBufferGlFbo::draw(QCPPainter *painter) const
{
  if (!painter || !painter->isActive())
  {
    qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed";
    return;
  }
  if (!mGlFrameBuffer)
  {
    qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?";
    return;
  }

// 添加这行代码即可
  if(QOpenGLContext::currentContext() != mGlContext.toStrongRef()){
      mGlContext.toStrongRef()->makeCurrent(mGlContext.toStrongRef()->surface());
  }

  painter->drawImage(0, 0, mGlFrameBuffer->toImage());
}

问题二:
在QCustomPlot的构造函数中,更改像素比列为从当前桌面获取。
setBufferDevicePixelRatio(QApplication::desktop()->devicePixelRatioF());

#  qcustomplot.cpp

QCustomPlot::QCustomPlot(QWidget *parent) :
  QWidget(parent),
  xAxis(0),
  yAxis(0),
  xAxis2(0),
  yAxis2(0),
  legend(0),
  mBufferDevicePixelRatio(1.0), // will be adapted to primary screen below
  mPlotLayout(0),
  mAutoAddPlottableToLegend(true),
  mAntialiasedElements(QCP::aeNone),
  mNotAntialiasedElements(QCP::aeNone),
  mInteractions(0),
  mSelectionTolerance(8),
  mNoAntialiasingOnDrag(false),
  mBackgroundBrush(Qt::white, Qt::SolidPattern),
  mBackgroundScaled(true),
  mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding),
  mCurrentLayer(0),
  mPlottingHints(QCP::phCacheLabels|QCP::phImmediateRefresh),
  mMultiSelectModifier(Qt::ControlModifier),
  mSelectionRectMode(QCP::srmNone),
  mSelectionRect(0),
  mOpenGl(false),
  mMouseHasMoved(false),
  mMouseEventLayerable(0),
  mMouseSignalLayerable(0),
  mReplotting(false),
  mReplotQueued(false),
  mOpenGlMultisamples(16),
  mOpenGlAntialiasedElementsBackup(QCP::aeNone),
  mOpenGlCacheLabelsBackup(true)
{
  setAttribute(Qt::WA_NoMousePropagation);
  setAttribute(Qt::WA_OpaquePaintEvent);
  setFocusPolicy(Qt::ClickFocus);
  setMouseTracking(true);
  QLocale currentLocale = locale();
  currentLocale.setNumberOptions(QLocale::OmitGroupSeparator);
  setLocale(currentLocale);
#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
#  ifdef QCP_DEVICEPIXELRATIO_FLOAT
  setBufferDevicePixelRatio(QApplication::desktop()->devicePixelRatioF());	//将代码中获取设备像素比例改成从桌面获取
//  setBufferDevicePixelRatio(QWidget::devicePixelRatioF());
#  else
  setBufferDevicePixelRatio(QWidget::devicePixelRatio());
#  endif
#endif
  
  mOpenGlAntialiasedElementsBackup = mAntialiasedElements;
  mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels);
  // create initial layers:
  mLayers.append(new QCPLayer(this, QLatin1String("background")));
  mLayers.append(new QCPLayer(this, QLatin1String("grid")));
  mLayers.append(new QCPLayer(this, QLatin1String("main")));
  mLayers.append(new QCPLayer(this, QLatin1String("axes")));
  mLayers.append(new QCPLayer(this, QLatin1String("legend")));
  mLayers.append(new QCPLayer(this, QLatin1String("overlay")));
  updateLayerIndices();
  setCurrentLayer(QLatin1String("main"));
  layer(QLatin1String("overlay"))->setMode(QCPLayer::lmBuffered);
  
  // create initial layout, axis rect and legend:
  mPlotLayout = new QCPLayoutGrid;
  mPlotLayout->initializeParentPlot(this);
  mPlotLayout->setParent(this); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry
  mPlotLayout->setLayer(QLatin1String("main"));
  QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true);
  mPlotLayout->addElement(0, 0, defaultAxisRect);
  xAxis = defaultAxisRect->axis(QCPAxis::atBottom);
  yAxis = defaultAxisRect->axis(QCPAxis::atLeft);
  xAxis2 = defaultAxisRect->axis(QCPAxis::atTop);
  yAxis2 = defaultAxisRect->axis(QCPAxis::atRight);
  legend = new QCPLegend;
  legend->setVisible(false);
  defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop);
  defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12));
  
  defaultAxisRect->setLayer(QLatin1String("background"));
  xAxis->setLayer(QLatin1String("axes"));
  yAxis->setLayer(QLatin1String("axes"));
  xAxis2->setLayer(QLatin1String("axes"));
  yAxis2->setLayer(QLatin1String("axes"));
  xAxis->grid()->setLayer(QLatin1String("grid"));
  yAxis->grid()->setLayer(QLatin1String("grid"));
  xAxis2->grid()->setLayer(QLatin1String("grid"));
  yAxis2->grid()->setLayer(QLatin1String("grid"));
  legend->setLayer(QLatin1String("legend"));
  
  // create selection rect instance:
  mSelectionRect = new QCPSelectionRect(this);
  mSelectionRect->setLayer(QLatin1String("overlay"));
  
  setViewport(rect()); // needs to be called after mPlotLayout has been created
  
  replot(rpQueuedReplot);
  }
  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值