Qwt QwtLegend和QwtPlotLegendItem图例类详解

news2024/11/15 23:39:33

1.概述

QwtLegend类是Qwt绘图库中用于显示图例的类。图例用于标识不同曲线、绘图元素或数据的意义,以便用户能够更好地理解图表中的数据。通过QwtLegend类,可以方便地在图表中添加、删除和设置图例的位置、方向和样式等属性。

QwtPlotLegendItem类是Qwt绘图库中用于在绘图中添加图例项的类。与QwtLegend类不同,QwtPlotLegendItem类是将图例项直接添加到绘图中,而不是作为独立的图例显示。可以将QwtPlotLegendItem对象与绘图对象相关联,以便在绘图中显示图例项。 

2. 常用方法

QwtPlotLegendItem常用方法介绍

设置最大列数

void setMaxColumns (uint)

设置对齐方式

void setAlignmentInCanvas (Qt::Alignment)

设置背景模式

void setBackgroundMode (BackgroundMode)

设置边框圆角

void setBorderRadius (double)

设置字体

void setFont (const QFont &)

设置外边距

void setItemMargin (int)

void setMargin (int)

设置距离

void setItemSpacing (int)

void setSpacing (int)

3.示例

源码:

//LegendWidget.h
#ifndef LEGENDWIDGET_H
#define LEGENDWIDGET_H

#include <QWidget>

namespace Ui {
class LegendWidget;
}

class QwtLegend;
class QwtPlotLegendItem;

class Settings
{
  public:
    Settings()
    {
        legend.isEnabled = false;
        legend.position = 0;

        legendItem.isEnabled = false;
        legendItem.numColumns = 0;
        legendItem.alignment = 0;
        legendItem.backgroundMode = 0;
        legendItem.size = 12;

        curve.numCurves = 0;
        curve.title = "Curve";
    }

    struct
    {
        bool isEnabled;
        int position;
    } legend;

    struct
    {
        bool isEnabled;
        int numColumns;
        int alignment;
        int backgroundMode;
        int size;

    } legendItem;

    struct
    {
        int numCurves;
        QString title;
    } curve;
};

class LegendWidget : public QWidget
{
    Q_OBJECT

public:
    explicit LegendWidget(QWidget *parent = 0);
    ~LegendWidget();

private:
    Settings settings() const;
    void applySettings( const Settings& );
    void insertCurve();

private slots:
    void on_cboxLegendEnabled_stateChanged(int arg1);

    void on_cbxPos_currentIndexChanged(int index);

    void on_cboxLegendItemEnabled_stateChanged(int arg1);

    void on_cbxHorizontal_currentIndexChanged(int index);

    void on_cbxVertical_currentIndexChanged(int index);

    void on_cbxBackGround_currentIndexChanged(int index);

    void on_spinBoxSize_valueChanged(int arg1);

    void on_spinBoxNum_valueChanged(int arg1);

    void on_leTitle_textEdited(const QString &arg1);

private Q_SLOTS:
  void edited();

  void on_spinBoxColumns_valueChanged(int arg1);

private:
  QwtLegend* m_externalLegend = nullptr;
  QwtPlotLegendItem* m_legendItem = nullptr;
  bool m_isDirty = false;

private:
    Ui::LegendWidget *ui;
};

#endif // LEGENDWIDGET_H



#include "LegendWidget.h"
#include "ui_LegendWidget.h"
#include "qwt_plot.h"
#include "qwt_plot_curve.h"
#include "qwt_text.h"
#include "qwt_legend.h"
#include "qwt_symbol.h"
#include "qwt_plot_marker.h"
#include "qwt_plot_grid.h"
#include "qwt_scale_div.h"
#include "qwt_plot_canvas.h"
#include "qwt_plot_legenditem.h"
#include "qwt_math.h"
#include "qwt_plot_layout.h"

class Curve : public QwtPlotCurve
{
  public:
    Curve( int index ):
        m_index( index )
    {
        setRenderHint( QwtPlotItem::RenderAntialiased );
        initData();
    }

    void setCurveTitle( const QString& title )
    {
        QString txt("%1 %2");
        setTitle( QString( "%1 %2" ).arg( title ).arg( m_index ) );
    }

    void initData()
    {
        QVector< QPointF > points;

        double y = qwtRand() % 1000;

        for ( double x = 0.0; x <= 1000.0; x += 100.0 )
        {
            double off = qwtRand() % 200 - 100;
            if ( y + off > 980.0 || y + off < 20.0 )
                off = -off;

            y += off;

            points += QPointF( x, y );
        }

        setSamples( points );
    }

  private:
    const int m_index;
};

class LegendItem : public QwtPlotLegendItem
{
  public:
    LegendItem()
    {
        setRenderHint( QwtPlotItem::RenderAntialiased );

        const QColor c1( Qt::white );

        setTextPen( c1 );
        setBorderPen( c1 );

        QColor c2( Qt::gray );
        c2.setAlpha( 200 );

        setBackgroundBrush( c2 );
    }
};

QwtPlot *g_plot = nullptr;

LegendWidget::LegendWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::LegendWidget)
{
    ui->setupUi(this);

    QwtPlotCanvas* canvas = new QwtPlotCanvas();
    canvas->setFocusIndicator( QwtPlotCanvas::CanvasFocusIndicator );
    canvas->setFocusPolicy( Qt::StrongFocus );
    canvas->setPalette( Qt::black );

    //创建plot
    g_plot = new QwtPlot(QwtText("图列示例"),this);
    g_plot->setFooter( "Footer" );
    g_plot->setAutoReplot( false );
    g_plot->setCanvas( canvas );

    //创建一个网格
    QwtPlotGrid* grid = new QwtPlotGrid;
    grid->enableXMin( true );
    grid->setMajorPen( Qt::gray, 0, Qt::DotLine );
    grid->setMinorPen( Qt::darkGray, 0, Qt::DotLine );
    grid->attach( g_plot );

    //设置坐标轴范围
    g_plot->setAxisScale( QwtAxis::YLeft, 0.0, 1000.0 );
    g_plot->setAxisScale( QwtAxis::XBottom, 0.0, 1000.0 );

    ui->hLayout->addWidget(g_plot);

    //初始化属性
    Settings settings;
    settings.legend.isEnabled = true;
    settings.legend.position = QwtPlot::BottomLegend;

    settings.legendItem.isEnabled = false;
    settings.legendItem.numColumns = 1;
    settings.legendItem.alignment = Qt::AlignRight | Qt::AlignVCenter;
    settings.legendItem.backgroundMode = 0;
    settings.legendItem.size = g_plot->canvas()->font().pointSize();

    settings.curve.numCurves = 4;
    settings.curve.title = "曲线";

    applySettings(settings);
}

LegendWidget::~LegendWidget()
{
    delete ui;
}

Settings LegendWidget::settings() const
{
    Settings s;

    s.legend.isEnabled =
        ui->cboxLegendEnabled->checkState() == Qt::Checked;
    s.legend.position = ui->cbxPos->currentIndex();

    s.legendItem.isEnabled =
        ui->cboxLegendItemEnabled->checkState() == Qt::Checked;
    s.legendItem.numColumns = ui->spinBoxColumns->value();

    int align = 0;

    int hIndex = ui->cbxHorizontal->currentIndex();
    if ( hIndex == 0 )
        align |= Qt::AlignLeft;
    else if ( hIndex == 2 )
        align |= Qt::AlignRight;
    else
        align |= Qt::AlignHCenter;

    int vIndex = ui->cbxVertical->currentIndex();
    if ( vIndex == 0 )
        align |= Qt::AlignTop;
    else if ( vIndex == 2 )
        align |= Qt::AlignBottom;
    else
        align |= Qt::AlignVCenter;

    s.legendItem.alignment = align;

    s.legendItem.backgroundMode =
        ui->cbxBackGround->currentIndex();
    s.legendItem.size = ui->spinBoxSize->value();

    s.curve.numCurves = ui->spinBoxNum->value();
    s.curve.title = ui->leTitle->text();

    return s;
}

void LegendWidget::applySettings(const Settings &settings)
{
    m_isDirty = false;
    g_plot->setAutoReplot( true );

    //判断图列是否启用
    if ( settings.legend.isEnabled )
    {
        //设置图列位置
        if ( settings.legend.position > QwtPlot::TopLegend )
        {
            //如果有,就先删除
            if ( g_plot->legend() )
            {
                // remove legend controlled by the plot
                g_plot->insertLegend( NULL );
            }

            //弹出的图列
            if ( m_externalLegend == NULL )
            {
                m_externalLegend = new QwtLegend();
                m_externalLegend->setWindowTitle("Plot Legend");

                connect(
                    g_plot,
                    SIGNAL(legendDataChanged(const QVariant&,const QList<QwtLegendData>&)),
                    m_externalLegend,
                    SLOT(updateLegend(const QVariant&,const QList<QwtLegendData>&)) );

                m_externalLegend->show();

                // populate the new legend
                g_plot->updateLegend();
            }
        }
        else
        {
            delete m_externalLegend;
            m_externalLegend = NULL;

            if ( g_plot->legend() == NULL ||
                g_plot->plotLayout()->legendPosition() != settings.legend.position )
            {
                g_plot->insertLegend( new QwtLegend(),
                    QwtPlot::LegendPosition( settings.legend.position ) );
            }
        }
    }
    else
    {
        g_plot->insertLegend( NULL );

        delete m_externalLegend;
        m_externalLegend = NULL;
    }

    //判断图例子项是否启用
    if ( settings.legendItem.isEnabled )
    {
        if ( m_legendItem == NULL )
        {
            m_legendItem = new LegendItem();
            m_legendItem->attach( g_plot );
        }

        //设置最大列数
        m_legendItem->setMaxColumns( settings.legendItem.numColumns );
        //设置对齐方式
        m_legendItem->setAlignmentInCanvas( Qt::Alignment( settings.legendItem.alignment ) );
        //设置背景模式
        m_legendItem->setBackgroundMode(
            QwtPlotLegendItem::BackgroundMode( settings.legendItem.backgroundMode ) );
        if ( settings.legendItem.backgroundMode ==
            QwtPlotLegendItem::ItemBackground )
        {
            m_legendItem->setBorderRadius( 4 );
            m_legendItem->setMargin( 0 );
            m_legendItem->setSpacing( 4 );
            m_legendItem->setItemMargin( 2 );
        }
        else
        {
            m_legendItem->setBorderRadius( 8 );
            m_legendItem->setMargin( 4 );
            m_legendItem->setSpacing( 2 );
            m_legendItem->setItemMargin( 0 );
        }

        //设置字体大小
        QFont font = m_legendItem->font();
        font.setPointSize( settings.legendItem.size );
        m_legendItem->setFont( font );
    }
    else
    {
        delete m_legendItem;
        m_legendItem = NULL;
    }

    //画曲线
    QwtPlotItemList curveList = g_plot->itemList( QwtPlotItem::Rtti_PlotCurve );
    if ( curveList.size() != settings.curve.numCurves )
    {
        while ( curveList.size() > settings.curve.numCurves )
        {
            QwtPlotItem* curve = curveList.takeFirst();
            delete curve;
        }

        for ( int i = curveList.size(); i < settings.curve.numCurves; i++ )
            insertCurve();
    }

    curveList = g_plot->itemList( QwtPlotItem::Rtti_PlotCurve );
    for ( int i = 0; i < curveList.count(); i++ )
    {
        Curve* curve = static_cast< Curve* >( curveList[i] );
        curve->setCurveTitle( settings.curve.title );

        int sz = 0.5 * settings.legendItem.size;
        curve->setLegendIconSize( QSize( sz, sz ) );
    }

    g_plot->setAutoReplot( false );
    if ( m_isDirty )
    {
        m_isDirty = false;
        g_plot->replot();
    }
}

void LegendWidget::insertCurve()
{
    static int counter = 1;

    const char* colors[] =
    {
        "LightSalmon",
        "SteelBlue",
        "Yellow",
        "Fuchsia",
        "PaleGreen",
        "PaleTurquoise",
        "Cornsilk",
        "HotPink",
        "Peru",
        "Maroon"
    };
    const int numColors = sizeof( colors ) / sizeof( colors[0] );

    QwtPlotCurve* curve = new Curve( counter++ );
    curve->setPen( QColor( colors[ counter % numColors ] ), 2 );
    curve->attach( g_plot );
}

void LegendWidget::on_cboxLegendEnabled_stateChanged(int arg1)
{
    edited();
}

void LegendWidget::on_cbxPos_currentIndexChanged(int index)
{
    edited();
}

void LegendWidget::on_cboxLegendItemEnabled_stateChanged(int arg1)
{
    edited();
}

void LegendWidget::on_cbxHorizontal_currentIndexChanged(int index)
{
    edited();
}

void LegendWidget::on_cbxVertical_currentIndexChanged(int index)
{
    edited();
}

void LegendWidget::on_cbxBackGround_currentIndexChanged(int index)
{
    edited();
}

void LegendWidget::on_spinBoxSize_valueChanged(int arg1)
{
    edited();
}

void LegendWidget::on_spinBoxNum_valueChanged(int arg1)
{
    edited();
}

void LegendWidget::on_leTitle_textEdited(const QString &arg1)
{
    edited();
}

void LegendWidget::edited()
{
    const Settings s = settings();
    applySettings( s);
}

void LegendWidget::on_spinBoxColumns_valueChanged(int arg1)
{
    edited();
}

4.完整工程

https://download.csdn.net/download/wzz953200463/88479580

此工程不包含qwt的库,需自行编译。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1141300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法训练营第三天 | 203.移除链表元素、707.设计链表 、206.反转链表

关于链表我们应该了解什么&#xff1a; 代码随想录 在实际开发中&#xff0c;遇到指针我们要做好防御性编程。 问题&#xff08; 一 &#xff09; 题目描述 &#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点…

H5营销观察:H5破圈传播有什么秘诀

在移动互联网时代&#xff0c;流量越加碎片化&#xff0c;场景变得相对短促和兴趣导向&#xff0c;一个营销H5产生的每一次点击、每一次互动、每一次流量停留背后都会有相应的动机&#xff0c;也是营销流量效果的成因。 今天&#xff0c;我们一起来探究下什么样的内容更容易传播…

calcite 校验层总结

1、校验的作用 1&#xff09;完善语义信息 例如在SQL语句中&#xff0c;如果碰到select * 这样的指令&#xff0c;在SQL的语义当中&#xff0c;“*” 指的是取出对应数据源中所有字段的信息&#xff0c;因此就需要根据元数据信息来展开。 2&#xff09;结合元数据信息来纠偏…

微服务-统一网关Gateway

网关的作用 对用户请求做身份认证、权限校验将用户请求路由到微服务&#xff0c;并实现负载均衡对用户请求做限流 搭建网关服务 创建新module&#xff0c;命名为Gateway&#xff0c;引入依赖&#xff08;1.SpringCloudGateway依赖&#xff1b;2.Eureka客户端依赖或者nacos的服…

web开发简单知识

文章目录 springboot快速入门快速构建SpringBoot工程起步依赖原理分析springboot配置配置文件分类yaml的基本语法yaml数据格式获取数据profile内部配置加载顺序外部配置加载顺序 springboot整合整合junit整合redis整合mybatis springboot原理分析springboot自动配置Condition 监…

“第五十二天”

算术逻辑单元&#xff1a; 之前提过的运算器包括MQ,ACC,ALU,X,PSW&#xff1b;运算器可以实现运算以及一些辅助功能&#xff08;移位&#xff0c;求补等&#xff09;。 其中ALU负责运算&#xff0c;运算包括算术运算&#xff08;加减乘除等&#xff09;和逻辑运算&#xff08…

蓝桥杯双周赛算法心得——通关(哈希+小根堆)

大家好&#xff0c;我是晴天学长&#xff0c;这是很重要的贪心思维题&#xff0c;哈希的存法和小根堆的表示很重要。 1) .通关 2) .算法思路 通关 用hash&#xff08;int[]&#xff09;存点的子节点并按输入顺序存关卡的号码&#xff08;输入顺序就是&#xff09; 列如&#…

Unity的live2dgalgame多语言可配置剧情框架

这段代码用于读取表格 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using OfficeOpenXml; using System.IO; using UnityEngine.Networking; using UnityEngine.UI; using Random UnityEngine.Random;public class Plots…

【Linux】部署单机OA项目及搭建spa前后端分离项目

一&#xff0c;部署oa项目 在虚拟机中&#xff0c;将项目打包成war文件放置到tomcat根目录下的webapps文件目录下 再在主机数据库中连接数据库&#xff0c;并定义数据库名导入相关的表 继续进入tomcat目录下双击点击startup.bat&#xff0c;启动oa项目 主机访问OA项目 如果登入…

MySQL之事务、存储引擎、索引

文章目录 前言一、事务1.概念2.操作&#xff08;1&#xff09;开启事务&#xff08;2&#xff09;提交事务&#xff08;3&#xff09;回滚事务 3.四大特性ACID&#xff08;1&#xff09;原子性&#xff08;Atomicity&#xff09;&#xff08;2&#xff09;一致性&#xff08;Co…

Web APIs——焦点事件以及小米搜索框

一、事件类型 二、焦点事件 <body><input type"text"><script>const input document.querySelector(input)input.addEventListener(focus,function(){console.log(有焦点触发)})input.addEventListener(blur,function(){console.log(失去焦点触…

H5新Api | requestIdleCallback - requestAnimationFram

文章目录 浏览器渲染机制事件循环机制宏队列与微队列浏览器中事件循环流程 requestAnimationFrame(rAF)requestAnimationFrame API requestIdleCallbackrequestIdleCallback API任务拆分requestIdleCallback的使用场景 浏览器渲染机制 每一轮 Event Loop 都会伴随着渲染吗&…

力扣:142. 环形链表 II(Python3)

题目&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评…

命令行参数、环境变量

我们在使用C语言的时候&#xff0c;经常的写法是int main(){//函数体}。 而且我们也知道它也只是一个函数&#xff0c;当一个进程启动的时候&#xff0c;会有专门的函数来调用这个函数。 那他有没有函数参数呢&#xff1f;其实也是有的&#xff0c;我们今天&#xff0c;就来认识…

常用的网络攻击手段

前言&#xff1a;本文旨在介绍目前常用的网络攻击手段&#xff0c;分享交流技术经验 目前常用的网络攻击手段 社会工程学攻击物理攻击暴力攻击利用Unicode漏洞攻击利用缓冲区溢出漏洞进行攻击等技术 社会工程学攻击 社会工程学 根据百度百科定义&#xff1a; 社会工…

2023/10/27 JAVA学习

tab键可以对文件名进行补全 想切到其他盘的某个文件,必须先使用切盘命令 在当前文件目录输入cmd,可直接打开命令行窗口,并且处于当前文件目录 运行java文件,只用文件名不需要后缀 记得勾选文件扩展名 直接这样执行不会出现class文件,因为在底层临时生成了一个,不会长久的出现

NX二次开发后处理中保存tcl变量值到文本

直接上代码&#xff1a; static bool GetTclValue(UF_MOM_id_t mom_id, char *szName, char *szInfo, std::string &stValue,bool bShowValue /* false*/) {UF_MOM_ask_string(mom_id, szName, (const char **)&szInfo);if (szInfo){stValue szInfo;if (bShowValue){…

ArrayList的线程安全类CopyOnWriteArrayList

目录 一、CopyOnWriteArrayList简介二、CopyOnWriteArrayList的优缺点1、优点2、缺点 三、CopyOnWriteArrayList使用场景1、数据库缓存2、消息队列3、数据统计和分析 四、使用CopyOnWriteArrayList时需要注意哪些问题&#xff1f;1、内存占用问题2、数据一致性问题3、线程安全4…

Milvus 入门教程

文章目录 下载docker-compose配置文件安装 docker安装docker-compose直接下载release版本手动安装使用pip 命令自动安装 通过 docker-compose 启动容器连接 Milvus停止 milvus删除milvus的数据 下载docker-compose配置文件 先安装wget命令 yum install wget下载配置文件&…