c++ - 使用带有 openGL 的 QLineSeries 时无法将 QChartView 正确保存为图像

标签 c++ qt opengl qchart

我正在尝试创建一个可以绘制大型数据集的应用程序(因此使用 OpenGl 对我来说很重要)。我使用 QChartViewQChartQLineSeries。同样对于 QLineSeries,我打开了 openGL 的使用。但是当我试图将图表保存为图像时,我得到了没有数据的图。我知道当 QLineSeries 使用 openGL 时,它会在图表绘图区域顶部创建一个 QOpenGLWidget,但我不知道如何访问它。

那么一个问题是:如何将图表保存为带有画线的图像?

一些图片:

我想要的(不使用 openGL 绘图):

Plot without using openGL

我得到了什么(用 openGL 绘图):

Plot with openGL

这是一个代码示例:

主窗口构造函数:

chartView = new QChartView(generate_sin_chart(), ui->centralWidget);
ui->centralWidget->layout()->addWidget(chartView);

generate_sin_chart():

QLineSeries *series = new QLineSeries();
series->setUseOpenGL(true); //this line cause a problem

constexpr double PI = 3.14159265359;
for(int i = 0; i < 100; ++i)
{
    double temp = i*PI/6;
    series->append(temp, sin(temp));
}

QChart *chart = new QChart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
chart->setTitle("Simple line chart example");

return chart;

保存函数:

QString filename = QFileDialog::getSaveFileName(this, tr("Save file"), "", tr("Images (*.png)"));
QPixmap p = chartView->grab();
p.save(filename, "PNG");

最佳答案

根据docs :

useOpenGL : bool

Specifies whether or not drawing the series is accelerated by using OpenGL.

Acceleration using OpenGL is supported only for QLineSeries and QScatterSeries. A line series used as an edge series for QAreaSeries cannot use OpenGL acceleration. When a chart contains any series that are drawn with OpenGL, a transparent QOpenGLWidget is created on top of the chart plot area. The accelerated series are not drawn on the underlying QGraphicsView, but are instead drawn on the created QOpenGLWidget.

[...]

所以当你使用grab()只对QChartView拍照时,解决方法是找到QOpenGLWidget对象并记录它QChartView 图像之上的图像,以下代码执行此操作:

QPixmap p = chartView->grab();
QOpenGLWidget *glWidget  = chartView->findChild<QOpenGLWidget*>();
if(glWidget){
    QPainter painter(&p);
    QPoint d = glWidget->mapToGlobal(QPoint())-chartView.mapToGlobal(QPoint());
    painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
    painter.drawImage(d, glWidget->grabFramebuffer());
    painter.end();
}
p.save("test", "PNG");

因为您应该使用QOpenGLWidget,所以您必须将QT += opengl 添加到您的.pro

一个完整的例子可以在下面的link中找到

关于c++ - 使用带有 openGL 的 QLineSeries 时无法将 QChartView 正确保存为图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48139716/

相关文章:

c++ - 在 QT 中,我们可以有两个名称相同但参数不同的插槽吗?

java - OpenGL - 颜色布局位置不起作用

c++ - 拥有一个包含很多(很多!) bool 字段的 C++ 类是否可以?

c++ - 在进行一些计数器操作时,我该如何做到,如果 setCounter() 没有参数,计数器将为零?

c++ - "No Matching Function for call"错误

Qt-QTreeView : How to show a checkbox in a themed application?

c++ - Qt Directx 渲染

linux - openGL MSAA 不适用于带有 nouveau 驱动程序的 linux

c++ - glfwDestroyWindow 不会关闭窗口

c++ - C++ 工具链和编译器之间有什么区别?