Skip to content

Instantly share code, notes, and snippets.

@mrchipset
Created October 18, 2023 01:06
Show Gist options
  • Save mrchipset/d90050aab6a04c5deb574b654def284f to your computer and use it in GitHub Desktop.
Save mrchipset/d90050aab6a04c5deb574b654def284f to your computer and use it in GitHub Desktop.
QCustomPlot Scale Bar Component
#include "ScaleBar.h"
ScaleBar::ScaleBar(QCustomPlot *plot)
: QObject{plot},
mPlot(plot)
{
mScaleBar = new QCPItemLine(mPlot);
QPen p(Qt::NoBrush, 1.5F);
p.setColor(Qt::red);
mScaleBar->setPen(p);
mScaleBar->setHead(QCPLineEnding::esBar);
mScaleBar->setTail(QCPLineEnding::esBar);
mScaleBar->setLayer("overlay");
mScaleLabel = new QCPItemText(mPlot);
mScaleLabel->setTextAlignment(Qt::AlignCenter);
mScaleLabel->setColor(Qt::red);
mScaleLabel->setText(tr("10 um"));
mScaleLabel->position->setType(QCPItemPosition::ptAbsolute);
connect(mPlot, &QCustomPlot::beforeReplot, this, &ScaleBar::onBeforePlot);
}
void ScaleBar::setVisible(bool visible)
{
mScaleBar->setVisible(visible);
mScaleLabel->setVisible(visible);
mPlot->replot(QCustomPlot::rpQueuedReplot);
}
const bool ScaleBar::visible() const
{
return mVisible;
}
void ScaleBar::setScale(uint32_t scale)
{
if (scale > 0) {
mScale = scale;
mPlot->replot(QCustomPlot::rpQueuedReplot);
}
}
uint32_t ScaleBar::scale() const
{
return mScale;
}
void ScaleBar::updateScaleBar()
{
if (!mVisible) {
return;
}
const QPoint btLeft = mPlot->xAxis->axisRect()->bottomLeft();
const QPoint btRight = mPlot->xAxis->axisRect()->bottomRight();
const QPoint tpLeft = mPlot->xAxis->axisRect()->topLeft();
const int x = btRight.x() - btLeft.x();
const int y = btLeft.y() - tpLeft.y();
mScaleBar->start->setType(QCPItemPosition::ptAbsolute);
mScaleBar->end->setType(QCPItemPosition::ptAbsolute);
const double range = mScale;
QPointF start = QPointF(btLeft) + QPointF(x * 0.05, -y * 0.05);
QPointF coordStart = QPointF(mPlot->xAxis->pixelToCoord(start.x()), mPlot->yAxis->pixelToCoord(start.y()));
QPointF coordEnd = coordStart + QPointF(range, 0);
const int sx = start.x();
const int sy = start.y();
const int ex = mPlot->xAxis->coordToPixel(coordEnd.x());
const int ey = mPlot->yAxis->coordToPixel(coordEnd.y());
mScaleBar->start->setPixelPosition(start);
mScaleBar->end->setPixelPosition(QPoint(ex, start.y()));
mScaleLabel->setText(tr("%1 um").arg(QString::number(mScale)));
QFontMetrics metric(mScaleLabel->font());
mScaleLabel->position->setPixelPosition(QPoint((ex + sx) / 2, ey - metric.height() / 2 - 2));
}
void ScaleBar::onBeforePlot()
{
updateScaleBar();
}
#ifndef SCALEBAR_H
#define SCALEBAR_H
#include <QObject>
#include "qcustomplot.h"
class ScaleBar : public QObject
{
Q_OBJECT
public:
explicit ScaleBar(QCustomPlot *plot);
void setVisible(bool visible);
const bool visible() const;
void setScale(uint32_t scale);
uint32_t scale() const;
Q_SIGNALS:
private:
QCustomPlot* mPlot{nullptr};
QCPItemLine* mScaleBar{nullptr};
QCPItemText* mScaleLabel{nullptr};
bool mVisible{true};
uint32_t mScale{10};
void updateScaleBar();
private Q_SLOTS:
void onBeforePlot();
};
#endif // SCALEBAR_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment