QCustomplot自定义游标样式

我想要自定义一个头朝右中间有字母的三角形游标,默认的样式没有可以用的,请问怎么做

引用new bing部分回答作答:
您可以使用QCustomPlot的QCPItemTracer类来创建自定义的游标。这个类允许您自定义游标的形状、颜色、大小等属性。

要创建一个头朝右中间有字母的三角形游标,您可以按照以下步骤进行操作:

1 创建一个QCPItemTracer对象:

QCPItemTracer *tracer = new QCPItemTracer(customPlot);


2 设置游标的形状为三角形,并调整大小:

tracer->setGraphKey(key); // 设置游标所在的数据点
tracer->setStyle(QCPItemTracer::tsTriangle); // 设置游标形状为三角形
tracer->setSize(10); // 设置游标大小


3 创建一个QCPItemText对象,并设置字母:

QCPItemText *text = new QCPItemText(customPlot);
text->setText("A"); // 设置字母
text->setPositionAlignment(Qt::AlignHCenter | Qt::AlignVCenter); // 设置字母在游标中心位置
text->position->setCoords(tracer->position()); // 设置字母位置为游标位置

4 将QCPItemText对象与QCPItemTracer对象关联:

tracer->addChild(text); // 将QCPItemText对象作为QCPItemTracer对象的子对象

5 调整游标的颜色和线宽:

tracer->setPen(QPen(Qt::red, 2)); // 设置游标线的颜色和线宽


6 在图表中添加游标:

customPlot->addItem(tracer); // 将QCPItemTracer对象添加到QCustomPlot对象中

最终的代码可能如下所示:

QCPItemTracer *tracer = new QCPItemTracer(customPlot);
tracer->setGraphKey(key);
tracer->setStyle(QCPItemTracer::tsTriangle);
tracer->setSize(10);

QCPItemText *text = new QCPItemText(customPlot);
text->setText("A");
text->setPositionAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
text->position->setCoords(tracer->position());

tracer->addChild(text);
tracer->setPen(QPen(Qt::red, 2));

customPlot->addItem(tracer);


这只是一个示例,您可以根据需要自定义游标的属性。

QCustomPlot是一个用于绘制图表和数据可视化的Qt C++库。为了创建一个自定义的头朝右、中间有字母的三角形游标样式,你可以通过以下步骤实现:

1.首先,确保你已经在项目中包含了QCustomPlot库。如果尚未添加,请访问http://www.qcustomplot.com/ 下载并将其添加到你的项目中。

2.你需要从QCPItemTracer类继承一个自定义类,并重写其draw方法。这个方法将负责绘制你的三角形游标。请参考以下代码

img


3. 使用自定义类在图表上添加三角形游标

img


这样,你就可以看到一个头朝右、中间有字母"A"的三角形游标显示在图表上。你可以根据需要修改三角形的大小、颜色和字母。

你可以这样自定义游标样式:

  1. 定义一个QCursor类,继承自QGraphicsItem




 cpp
 class Cursor : public QGraphicsItem
 {
 public:
     Cursor();
     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
 };

  1. 重写paint方法,在里面绘制你的三角形游标




 cpp
 void Cursor::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 
 {
     painter->setPen(Qt::NoPen);
     painter->setBrush(Qt::red);
     QPointF points[3] = {
         QPointF(0, 10),
         QPointF(20, 10),
         QPointF(10, 0)
     };
     painter->drawPolygon(points, 3);
     painter->drawText(QPointF(15, 12), "A");  // 绘制字母A
 } 

  1. 在绘图区域增加你的游标实例




 cpp
 Cursor *cursor = new Cursor;
 plot->scene()->addItem(cursor);

  1. 重写mouseMoveEvent方法,更新游标的位置




 cpp
 void Plot::mouseMoveEvent(QMouseEvent *event) 
 {
     cursor->setPos(event->pos());  // 更新游标位置
 }
  1. 重写setCursor方法,返回一个空的Cursor,隐藏系统默认游标
 cpp 
 void Plot::setCursor(const QCursor &cursor)
 {
     Q_UNUSED(cursor)
 }

这样你就完成了一个自定义的三角形游标,在mouseMove事件下会跟随鼠标位置更新。由于重写了setCursor方法返回一个空游标,所以会隐藏系统默认的鼠标样式,只显示你的自定义游标。

希望这个示例能帮助你实现自定义游标的需求。如有任何其他问题,欢迎在评论中提出。

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/343205
  • 这篇博客也不错, 你可以看下QCustomPlot使用
  • 除此之外, 这篇博客: QCustomPlot 的使用 散点图 升级版(菜单、图例、鼠标显示值)中的 QCustomPlot 的使用 散点图 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 前沿:在自身不断的努力下,对散点图进行了优化
    设计到的知识点

    1. 散点的绘制,值得注意的是,如果需要绘制多层的话,需要加入customplot->addGraph();// 增加图层
      不然会报错,错误如下图。
      在这里插入图片描述
      代码如下:
    // 设置画笔风格
    	QPen drawPen;
    	drawPen.setColor(Qt::red);
    	drawPen.setWidth(4);
    
    	// 绘制散点
    	QCPGraph * curGraph = customplot->graph(0);
    	curGraph->setPen(drawPen);
    	curGraph->setLineStyle(QCPGraph::lsNone);
    	curGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 2));//点是空心的
    	//ssDisc 点是实心的,需要改变参数即可
    	customplot->graph(0)->setName(QString::fromLocal8Bit("你是憨批"));// 图例的名字
    	
    // 设置画笔风格
    	QPen drawPen1;
    	drawPen1.setColor(Qt::black);
    	drawPen1.setWidth(4);
    
    	// 绘制散点
    	customplot->addGraph();
    	QCPGraph * curGraph1 = customplot->graph(1);
    	curGraph1->setPen(drawPen1);
    	curGraph1->setLineStyle(QCPGraph::lsNone);//曲线样式
    	curGraph1->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 2));//点是空心的
    	customplot->graph(1)->setName(QString::fromLocal8Bit("我是耙耳朵"));// 图例的名字
    
    1. 图例的添加
      customplot->graph(1)->setName(QString::fromLocal8Bit(“我是耙耳朵”));// 设置图例的名字,我把这句代码放在前面了
    	customplot->legend->setVisible(true); //设置图例是否可用
    	QFont legendFont = font();
    	legendFont.setPointSize(10);
    	customplot->legend->setFont(legendFont);
    	customplot->legend->setSelectedFont(legendFont);
    	customplot->legend->setSelectableParts(QCPLegend::spItems); // legend box shall not be selectable, only legend items
    	
    //后面的为补充,可以不加
    	//设置图例图标大小
    	customplot->legend->setIconSize(5, 5);
    
    	//设置图例文字颜色
    	customplot->legend->setTextColor(Qt::red);//设置图例文字颜色
    
    	//在图例中添加线
    	customplot->axisRect()->setupFullAxesBox();
    
    	//将图例矩形域放到右上角
    	customplot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignTop | Qt::AlignRight);
    
    	//设置图例背景色
    	customplot->legend->setBrush(QColor(255, 255, 255, 0));//设置背景色
    
    1. 添加图的标题
    	customplot->plotLayout()->insertRow(0);
    	QCPTextElement *title = new QCPTextElement(customplot, "my love chart", QFont("sans", 17, QFont::Bold));
    	customplot->plotLayout()->addElement(0, 0, title);
    
    1. 菜单的添加(实现的是对图例位置的设置) 如果想右键图出现菜单,则注释if语句
    	customplot->setContextMenuPolicy(Qt::CustomContextMenu);
    	connect(customplot, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequest(QPoint)));
    	
    //槽函数的编写
    //菜单的生成
    void CustomPoltWidget::contextMenuRequest(QPoint pos)
    {
    	QMenu *menu = new QMenu(this);
    	menu->setAttribute(Qt::WA_DeleteOnClose);
     	if (customplot->legend->selectTest(pos, false) >= 0) // context menu on legend requested
     	{
    		menu->addAction("Move to top left", this, SLOT(moveLegend()))->setData((int)(Qt::AlignTop | Qt::AlignLeft));
    		menu->addAction("Move to top center", this, SLOT(moveLegend()))->setData((int)(Qt::AlignTop | Qt::AlignHCenter));
    		menu->addAction("Move to top right", this, SLOT(moveLegend()))->setData((int)(Qt::AlignTop | Qt::AlignRight));
    		menu->addAction("Move to bottom right", this, SLOT(moveLegend()))->setData((int)(Qt::AlignBottom | Qt::AlignRight));
    		menu->addAction("Move to bottom left", this, SLOT(moveLegend()))->setData((int)(Qt::AlignBottom | Qt::AlignLeft));
    	}
    	menu->popup(customplot->mapToGlobal(pos));
    }
    //图例的移动
    void CustomPoltWidget::moveLegend()
    {
    	if (QAction* contextAction = qobject_cast<QAction*>(sender())) // make sure this slot is really called by a context menu action, so it carries the data we need
    	{
    		bool ok;
    		int dataInt = contextAction->data().toInt(&ok);
    		if (ok)
    		{
    			customplot->axisRect()->insetLayout()->setInsetAlignment(0, (Qt::Alignment)dataInt);
    			customplot->replot();
    		}
    	}
    }
    
    

引用chatGPT作答,要自定义一个头朝右中间有字母的三角形游标,可以通过以下步骤实现:

1.创建一个新的QCPItemPixmap对象,并加载一个包含三角形和字母的图像文件,或者直接在代码中创建一个QPixmap对象。

2.使用QCustomPlot的additem方法将该对象添加到图表中。在添加对象时,可以指定三角形游标的位置、大小和旋转角度等属性。

3.使用QCustomPlot的replot()方法刷新图表,以便新的游标对象显示出来。

下面是一个简单的示例代码,演示如何自定义一个头朝右中间有字母的三角形游标:

// 创建一个包含三角形和字母的图像文件,并加载到QPixmap对象中
QPixmap pixmap(":/images/triangle.png");

// 创建一个QCPItemPixmap对象,并将其添加到图表中
QCPItemPixmap *cursor = new QCPItemPixmap(customPlot);
cursor->setPixmap(pixmap);
cursor->setScaled(true, Qt::IgnoreAspectRatio);
cursor->setPen(Qt::NoPen);
cursor->setBrush(Qt::NoBrush);
cursor->setOffset(QPointF(5, 5)); // 位置偏移量
cursor->setRotation(90); // 旋转角度
customPlot->addItem(cursor);

// 设置游标的位置和大小
cursor->setClipToAxisRect(false);
cursor->topLeft->setCoords(0, 0);
cursor->bottomRight->setCoords(50, 50);

// 刷新图表
customPlot->replot();

在这个示例中,我们首先创建了一个包含三角形和字母的图像文件,并将其加载到QPixmap对象中。然后,我们创建了一个QCPItemPixmap对象,并将其添加到图表中。在设置游标对象的属性时,我们使用了一些常用的属性,如位置偏移量、旋转角度、大小和位置等。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
QCPItemTracer是QCustomPlot中的游标,它包括一个可定位的箭头和一个可选的标签。QCustomPlot提供了一些预定义的游标样式(例如水滴、十字架等),但是您也可以创建自己的游标图形和文本。

关于如何自定义游标样式,可以按照以下步骤操作:

  1. 派生一个新的QCPItemTracer子类,例如MyTracer,并在其构造函数中设置箭头、线段和文本。
MyTracer::MyTracer(QCPAxis *axis):
    QCPItemTracer(axis) // 调用基类的构造函数
{
    // 创建游标箭头,使用一个三角形代替箭头的头部
    QPolygon arrowPolygon;
    arrowPolygon << QPoint(0, 0) << QPoint(10, -5) << QPoint(10, 5);
    QCPItemLine *arrow = new QCPItemLine(this->parentPlot());
    arrow->setHead(QCPLineEnding::None);
    arrow->setClipToAxisRect(false); // 箭头不受坐标轴的限制
    arrow->setPen(QPen(QColor(255, 100, 0))); // 设置箭头的颜色
    arrow->setHead(QCPLineEnding(QCPLineEnding::Polygon, arrowPolygon)); // 设置箭头的形状
    setHead(arrow); // 设置箭头属性

    // 创建文本,居中在游标上
    QCPItemText *text = new QCPItemText(this->parentPlot());
    text->setClipToAxisRect(false); // 文本不受坐标轴的限制
    text->setColor(QColor(255, 100, 0)); // 设置字体颜色
    text->setText("Arrow"); // 设置文本内容
    text->setPositionAlignment(Qt::AlignRight|Qt::AlignHCenter); // 文本居中对齐
    setLabel(text); // 设置文本属性

    // 创建游标线段,一个长条垂直于坐标轴
    QCPItemLine *line = new QCPItemLine(this->parentPlot());
    line->setClipToAxisRect(false); // 线段不受坐标轴的限制
    line->setPen(QPen(QColor(255, 100, 0))); // 设置线段的颜色
    line->setHead(QCPLineEnding::None);
    setTail(line); // 设置线段属性
}
  1. 在需要的地方使用MyTracer来替换默认的游标,例如:
QCPItemTracer *tracer = new MyTracer(ui->plot->xAxis);
tracer->setGraph(graph);
tracer->setInterpolating(false); // 关闭插值

这样就可以自定义游标样式了。

下面是一个完整的例子(基于QCustomPlot 2.0.0):

#include <QApplication>
#include <QWidget>
#include <qcustomplot.h>

class MyTracer : public QCPItemTracer
{
public:
    MyTracer(QCPAxis *axis) :
        QCPItemTracer(axis)
    {
        // 创建游标箭头
        QPolygon arrowPolygon;
        arrowPolygon << QPoint(0, 0) << QPoint(10, -5) << QPoint(10, 5);
        QCPItemLine *arrow = new QCPItemLine(this->parentPlot());
        arrow->setHead(QCPLineEnding::None);
        arrow->setClipToAxisRect(false);
        arrow->setPen(QPen(QColor(255, 100, 0)));
        arrow->setHead(QCPLineEnding(QCPLineEnding::Polygon, arrowPolygon));
        setHead(arrow);

        // 创建文本,居中在游标上
        QCPItemText *text = new QCPItemText(this->parentPlot());
        text->setClipToAxisRect(false);
        text->setColor(QColor(255, 100, 0));
        text->setText("Arrow");
        text->setPositionAlignment(Qt::AlignRight|Qt::AlignHCenter);
        setLabel(text);

        // 创建游标线段
        QCPItemLine *line = new QCPItemLine(this->parentPlot());
        line->setClipToAxisRect(false);
        line->setPen(QPen(QColor(255, 100, 0)));
        line->setHead(QCPLineEnding::None);
        setTail(line);
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget *window = new QWidget;
    QVBoxLayout *layout = new QVBoxLayout;
    window->setLayout(layout);

    QCustomPlot *plot = new QCustomPlot;
    plot->setMinimumSize(500, 500);

    // 添加一条曲线
    QVector<double> x(101), y(101);
    for (int i=0; i<101; ++i)
    {
        x[i] = i/50.0-1;
        y[i] = x[i]*x[i];
    }
    QCPGraph *graph = plot->addGraph();
    graph->setData(x, y);
    graph->setPen(QPen(Qt::green));

    // 更改游标样式
    QCPItemTracer *tracer = new MyTracer(plot->xAxis);
    tracer->setGraph(graph);
    tracer->setInterpolating(false);

    layout->addWidget(plot);

    window->show();
    return app.exec();
}

效果截图如下:

![自定义游标样式](https://i/