【QCustomPlot08】布局系统QCPLayout
【QCustomPlot08】布局系统QCPLayout一、布局基类二、具体布局类1、QCPLayoutGrid2、QCPAxisRect坐标轴矩形3、QCPLayoutInset嵌入布局原创作者郑同学的笔记原文链接https://zhengjunxue.blog.csdn.net/article/details/155240746在使用 QCustomPlot 进行绘图时了解其布局系统是非常重要的。QCustomPlot 提供了灵活的布局管理器使得我们可以轻松地安排图表和其他元素的位置。以下是关于 QCustomPlot 布局系统的简要教程和简单的 demo 示例。一、布局基类QCPLayoutQCPLayout 是所有布局类的基类。它提供了添加、移除和排列布局元素的基本功能。QCPLayoutElementQCPLayoutElement 是布局中单个元素的基类。它可以是任何东西比如一个图表、一个标签等。#includemainwindow.h#includeui_mainwindow.h#includeQTimer#includemywidget.hMainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui-setupUi(this);QCustomPlot*customPlotnewQCustomPlot(this);setCentralWidget(customPlot);{qDebug()plotLayout type:customPlot-plotLayout()-metaObject()-className();qDebug()element count:customPlot-plotLayout()-elementCount();qDebug()element(0) is AxisRect?(customPlot-plotLayout()-elementAt(0)-metaObject()-className()QByteArray(QCPAxisRect));}customPlot-replot();}MainWindow::~MainWindow(){deleteui;}默认情况下customPlot-plotLayout() 是什么当你创建一个 QCustomPlot 对象例如 new QCustomPlot(this)后它内部已经自动创建了一个默认的布局结构QCPLayoutGrid*defaultLayoutnewQCPLayoutGrid;QCPAxisRect*defaultAxisRectnewQCPAxisRect(this);defaultLayout-addElement(0,0,defaultAxisRect);也就是说plotLayout() 返回的是一个 QCPLayoutGrid 类型的对象虽然是基类指针但实际是 QCPLayoutGrid 实例。这个默认的 QCPLayoutGrid 在 (0, 0) 位置已经包含了一个 QCPAxisRect即默认的绘图区域。所以你调用 customPlot-addGraph() 时图形会自动绘制在这个默认的 QCPAxisRect 中。二、具体布局类1、QCPLayoutGridQCPLayoutGrid 实现了一个网格布局允许你以行列的形式组织子元素。示例#includemainwindow.h#includeui_mainwindow.h#includeQTimer#includemywidget.hMainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui-setupUi(this);QCustomPlot*customPlotnewQCustomPlot(this);setCentralWidget(customPlot);// 创建网格布局QCPLayoutGrid*gridnewQCPLayoutGrid;grid-setColumnStretchFactor(0,1);// 可选设置列伸缩比例grid-setRowStretchFactor(0,1);// 添加四个文本元素grid-addElement(0,0,newQCPTextElement(customPlot,Cell (0,0),QFont(Arial,12,QFont::Bold)));grid-addElement(0,1,newQCPTextElement(customPlot,Cell (0,1),QFont(Arial,12,QFont::Bold)));grid-addElement(1,0,newQCPTextElement(customPlot,Cell (1,0),QFont(Arial,12,QFont::Bold)));grid-addElement(1,1,newQCPTextElement(customPlot,Cell (1,1),QFont(Arial,12,QFont::Bold)));// 替换默认布局customPlot-plotLayout()-clear();customPlot-plotLayout()-addElement(0,0,grid);customPlot-replot();}MainWindow::~MainWindow(){deleteui;}2、QCPAxisRect坐标轴矩形QCPAxisRect 用于包含坐标轴和它们之间的矩形区域。通常用于放置图形。#includemainwindow.h#includeui_mainwindow.h#includeQTimer#includemywidget.hMainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui-setupUi(this);QCustomPlot*customPlotnewQCustomPlot(this);setCentralWidget(customPlot);// 清空默认布局默认有一个 AxisRectcustomPlot-plotLayout()-clear();// 创建新的 AxisRectQCPAxisRect*axisRectnewQCPAxisRect(customPlot);customPlot-plotLayout()-addElement(0,0,axisRect);// 准备数据QVectordoublex(100),y(100);for(inti0;i100;i){x[i]i*0.1;y[i]qSin(x[i]);}// 在新 AxisRect 中添加图形QCPGraph*graphcustomPlot-addGraph(axisRect-axis(QCPAxis::atBottom),axisRect-axis(QCPAxis::atLeft));graph-setData(x,y);graph-setPen(QPen(Qt::blue));// 自动调整坐标轴范围axisRect-axis(QCPAxis::atBottom)-rescale();axisRect-axis(QCPAxis::atLeft)-rescale();customPlot-replot();}MainWindow::~MainWindow(){deleteui;}3、QCPLayoutInset嵌入布局功能在主图表上叠加一个浮动的“小窗口”inset显示额外信息。#includemainwindow.h#includeui_mainwindow.h#includeQTimer#includemywidget.hMainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui-setupUi(this);QCustomPlot*customPlotnewQCustomPlot(this);setCentralWidget(customPlot);// 绘制主图比如一条直线QVectordoublex(2),y(2);x[0]0;y[0]0;x[1]1;y[1]1;customPlot-addGraph();customPlot-graph(0)-setData(x,y);customPlot-xAxis-setRange(0,1);customPlot-yAxis-setRange(0,1);// 创建 Inset 布局必须附加到某个 QCPAxisRectQCPLayoutInset*insetLayoutnewQCPLayoutInset;// 创建一个文本元素作为 inset 内容QCPTextElement*textnewQCPTextElement(customPlot,Inset\nLabel,QFont(Arial,10));text-setTextColor(Qt::red);// 将文本添加到 inset 布局中位置为 (x10, y10, width80, height40)单位是像素insetLayout-addElement(text,QRect(10,10,80,40));// 将 inset 布局添加到默认的 AxisRect即 plotLayout()-element(0,0)QCPAxisRect*mainAxisRectcustomPlot-axisRect();// 默认的 AxisRectmainAxisRect-insetLayout()-setInsetAlignment(0,Qt::AlignTop|Qt::AlignLeft);// 注意QCPLayoutInset 必须通过 axisRect()-insetLayout() 使用// 所以上面我们直接操作默认 axisRect 的 insetLayout// 实际上不需要手动 new QCPLayoutInset —— 它已经存在// 正确做法直接使用内置的 insetLayoutcustomPlot-axisRect()-insetLayout()-addElement(text,Qt::AlignTop|Qt::AlignLeft);customPlot-replot();}MainWindow::~MainWindow(){deleteui;}综合应用#includemainwindow.h#includeui_mainwindow.h#includeQTimer#includemywidget.hMainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui-setupUi(this);QCustomPlot*customPlotnewQCustomPlot(this);setCentralWidget(customPlot);// 第一行添加轴矩形并绘制图表QCPAxisRect*axisRectnewQCPAxisRect(customPlot);customPlot-plotLayout()-addElement(0,0,axisRect);// 位置(0,0)// 绘制主图比如一条直线QVectordoublex(2),y(2);x[0]0;y[0]0;x[1]1;y[1]1;customPlot-addGraph();customPlot-graph(0)-setData(x,y);// 第二行添加网格布局QCPLayoutGrid*gridLayoutnewQCPLayoutGrid;gridLayout-addElement(0,0,newQCPTextElement(customPlot,Top Left));gridLayout-addElement(0,1,newQCPTextElement(customPlot,Top Right));gridLayout-addElement(1,0,newQCPTextElement(customPlot,Bottom Left));gridLayout-addElement(1,1,newQCPTextElement(customPlot,Bottom Right));customPlot-plotLayout()-addElement(1,0,gridLayout);// 位置(1,0)// 第三行插入布局占20%高度QCPLayoutInset*insetLayoutnewQCPLayoutInset;// 使用相对坐标而不是绝对坐标QCPTextElement*insetTextnewQCPTextElement(customPlot,Inset Text,QFont(Arial,12,QFont::Bold));insetText-setTextColor(Qt::red);// 设置醒目的颜色// 使用相对位置 (0.1, 0.1) 到 (0.9, 0.9) 表示在可用空间的10%到90%范围内insetLayout-addElement(insetText,Qt::AlignTop|Qt::AlignLeft);customPlot-plotLayout()-addElement(2,0,insetLayout);// 设置行拉伸因子确保所有行都可见customPlot-plotLayout()-setRowStretchFactor(0,3);// 图表占3份customPlot-plotLayout()-setRowStretchFactor(1,1);// 网格布局占1份customPlot-plotLayout()-setRowStretchFactor(2,1);// 插入布局占1份customPlot-replot();}MainWindow::~MainWindow(){deleteui;}