效果:
把视图、水平标尺、垂直标尺用网格布局放置。
每当拖动视图的滚动条时,更新标尺的偏移量:
connect(deviceGraphicsView->horizontalScrollBar(),&QScrollBar::valueChanged,[this,horizontalRuler]
{
horizontalRuler->setOffset(deviceGraphicsView->mapToScene(0,0).x());
});
connect(deviceGraphicsView->verticalScrollBar(),&QScrollBar::valueChanged,[this,verticalRuler]
{
verticalRuler->setOffset(deviceGraphicsView->mapToScene(0,0).y());
});
标尺刻度刷新原理:将视图左上角的点转成场景中的点得到偏移量再赋给标尺并刷新。
标尺红色游标刷新原理:鼠标在视图中移动时发送位置,使用此位置更新游标位置:
void GraphicsView::mouseMoveEvent(QMouseEvent *event)
{
emit mouseMovePos(event->pos());
return QGraphicsView::mouseMoveEvent(event);
}
connect(deviceGraphicsView,&GraphicsView::mouseMovePos,[horizontalRuler,verticalRuler](QPointF pos)
{
horizontalRuler->setSlidingLinePos(pos.x());
verticalRuler->setSlidingLinePos(pos.y());
});
附上标尺完整代码:
#ifndef RULERWIDGET_H
#define RULERWIDGET_H
#include <QWidget>
class RulerWidget : public QWidget
{
Q_OBJECT
public:
RulerWidget(Qt::Orientations orientation, QWidget *parent = nullptr);
~RulerWidget()override;
void setOffset(int value)
{
offset = value;
update();
}
void setSlidingLinePos(int pos)
{
slidingLinePos = pos + offset;
update();
}
protected:
void paintEvent(QPaintEvent *event)override;
private:
QColor backgroundColor{Qt::white};//背景色
QColor textAndLineColor{"#606060"};//文本和刻度颜色
QColor slidingLineColor{"#D56161"};//游标颜色
Qt::Orientations orientation;
int slidingLinePos{0};
int offset{0};
QFont font{"微软雅黑",16};
};
#endif // RULERWIDGET_H
#include "rulerwidget.h"
#include <QPainter>
#include <QPaintEvent>
#include <QTimer>
RulerWidget::RulerWidget(Qt::Orientations orientation,QWidget *parent)
: QWidget(parent),
orientation(orientation)
{
orientation == Qt::Horizontal ? setFixedHeight(60) : setFixedWidth(100);
slidingLineColor.setAlphaF(0.7);
}
RulerWidget::~RulerWidget()
{
}
void RulerWidget::paintEvent(QPaintEvent *event)
{
auto rect = event->rect();
auto height = rect.height();
auto width = rect.width();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.fillRect(rect,backgroundColor);
orientation == Qt::Horizontal ? painter.translate(0 - offset,0) : painter.translate(0,0 - offset);
//绘制刻度
painter.save();
auto length = (orientation == Qt::Horizontal ? rect.width() : rect.height()) + offset;
painter.setPen(QPen(textAndLineColor,1));
painter.setFont(font);
if(orientation == Qt::Horizontal)
{
auto shortLine_y = height * 0.75;
auto longLine_y = height * 0.5;
auto middleLine_y = height * 0.625;
auto halfHeight = height / 2;
int temp = 0;
for(int i = 0;i < length;i+=10)
{
if(temp % 10 == 0)//画长线
{
painter.drawLine(QPointF(i,middleLine_y),QPointF(i,height));
}
else if(temp % 5 == 0)
{
painter.drawLine(QPointF(i,longLine_y),QPointF(i,height));
painter.drawText(QRectF(i-50,0,100,halfHeight),Qt::AlignCenter | Qt::TextWordWrap,QString::number(i));
}
else
{
painter.drawLine(QPointF(i,shortLine_y),QPointF(i,height));
}
++temp;
}
}
else
{
auto shortLineWidth = width * 0.25;
auto longLineWidth = width * 0.5;
auto middleLineWidth = width * 0.375;
auto harfWidth = width / 2;
int temp = 0;
for(int i = 0;i < length;i+=10)
{
if(temp % 10 == 0)//画长线
{
painter.drawLine(QPointF(middleLineWidth,i),QPointF(0,i));
}
else if(temp % 5 == 0)
{
painter.drawLine(QPointF(longLineWidth,i),QPointF(0,i));
painter.drawText(QRectF(harfWidth,i-50,harfWidth,100),Qt::AlignCenter | Qt::TextWordWrap,QString::number(i));
}
else
{
painter.drawLine(QPointF(shortLineWidth,i),QPointF(0,i));
}
++temp;
}
}
painter.restore();
painter.setPen(Qt::transparent);
painter.setBrush(slidingLineColor);
if(orientation == Qt::Horizontal)
{
painter.drawRect(slidingLinePos,0,3,height);
}
else
{
painter.drawRect(0,slidingLinePos,width,3);
}
QWidget::paintEvent(event);
}
相关博文:Qt编写自定义控件:像素刻度尺