charview.h
#ifndef CHARVIEW_H
#define CHARVIEW_H
#include
#include
#include
#include
#include
#include
#include
class ScaleNode
{
public:
QPointF pointScaleOne;
QPointF pointScaleTwo;
QPointF pointScaleText;
double scaleValue;
bool bShowScaleText;
ScaleNode* nextNode;
ScaleNode(){
bShowScaleText = false;
nextNode = nullptr;
}
};
class CharView: public QWidget
{
public:
CharView(QWidget *parent = nullptr);
~CharView();
virtual void paintAxisX(QPainter &painter);
virtual void paintAxisY(QPainter &painter);
virtual void paintCursor(QPainter &painter);
virtual void paintData(QPainter &painter);
virtual void paintMouseRightMove(QPainter &painter);
void UpdeScaleNode();
void InitScaleNode();
void MouseLeftMoveUpdateStartEndValue();//鼠标左键拖动更新
void MouseRightMoveUpdateStartEndValue();//鼠标右键选择更新
void MouseWheelUpdateStartEndValue(int flag);//鼠标缩放更新
private:
void DeleteNode(ScaleNode* node);
protected:
virtual void paintEvent(QPaintEvent* event) override;
virtual void resizeEvent(QResizeEvent* event) override;
virtual void mouseMoveEvent(QMouseEvent* event) override;
virtual void mousePressEvent(QMouseEvent* event) override;//鼠标左键按住拖动移动, 右键区域放大
virtual void mouseReleaseEvent(QMouseEvent* event) override;
virtual void wheelEvent(QWheelEvent* event) override;//滚动鼠标滑轮放大缩小
virtual void mouseDoubleClickEvent(QMouseEvent* event) override;//双击恢复默认
public:
int leftBorder;
int topBorder;
int rightBorder;
int bottomBorder;
double scaleValue;
int scaleLength;//刻度线高度
int scaleTextScaleLength;//带text的刻度线高度
int scaleTextHeight;//刻度text高度
int scaleTextWidth;//刻度text宽度
int scaleTextBorder;//刻度text边距
int scaleCnt;//刻度数量
double scaleWidth;//刻度宽度
int scaleCntShowText;//每多少个刻度显示刻度text
double startScaleValueInit;//默认刻度开始值
double endScaleValueInit;//默认刻度结束值
double startScaleValue;//当前刻度开始值
double endScaleValue;//当前刻度结束值
double everyWidthValue;//每个宽度的值
ScaleNode* scaleNodeBegin;//第一个刻度
QPointF currentPointF;//当前鼠标位置
bool bShowCursor;//是否实现游标
bool bPressLeft;//是否鼠标左键按下
bool bPressRight;//是否鼠标右键按下
QPointF pressPointF;//鼠标左键按下时坐标
bool bPressRightMove;//鼠标是否按下移动
};
#endif // CHARVIEW_H
CharView.cpp
#include "charview.h"
#include
CharView::CharView(QWidget *parent):
QWidget(parent)
{
setMouseTracking(true);
setStyleSheet("background-color:rgb(255,255,255);");
InitScaleNode();
}
CharView::~CharView()
{
DeleteNode(scaleNodeBegin);
}
void CharView::DeleteNode(ScaleNode *node)
{
if(node->nextNode)
DeleteNode(node->nextNode);
delete node;
node = nullptr;
}
void CharView::UpdeScaleNode()
{
scaleValue = ((double)(endScaleValue - startScaleValue))/scaleCnt;
scaleWidth = ((double)(width() - leftBorder - rightBorder))/scaleCnt;
everyWidthValue = ((double)(endScaleValue - startScaleValue))/(width() - leftBorder - rightBorder);
ScaleNode* node = scaleNodeBegin;
int var=0;
while(node){
node->pointScaleOne = QPointF(leftBorder + var*scaleWidth, height() - bottomBorder);
node->pointScaleTwo = QPointF(leftBorder + var*scaleWidth, height() - bottomBorder - scaleLength);
node->pointScaleText = QPointF(leftBorder + var*scaleWidth - scaleTextWidth/2, height() - bottomBorder + scaleTextBorder);
node->scaleValue = startScaleValue + var*scaleValue;
if(var%scaleCntShowText == 0)
{
node->pointScaleTwo = QPointF((double)(leftBorder + var*scaleWidth), height() - bottomBorder - scaleTextScaleLength);
node->bShowScaleText = true;
}
var++;
node = node->nextNode;
}
}
void CharView::InitScaleNode()
{
bPressRightMove = false;
bPressLeft = false;
bPressRight = false;
bShowCursor = true;
leftBorder = 50;
topBorder = 10;
rightBorder = 50;
bottomBorder = 20;
scaleCntShowText = 5;
startScaleValueInit = 0;
endScaleValueInit = 3000000000;
startScaleValue = startScaleValueInit;
endScaleValue = endScaleValueInit;
scaleCnt = 30;
scaleLength = 2;
scaleTextScaleLength = 4;
scaleTextBorder = 5;
scaleTextWidth = 100;
scaleTextHeight = fontMetrics().height();
ScaleNode* nodeTmp=nullptr;
for (int var = 0; var <= scaleCnt; ++var) {
ScaleNode* node = new ScaleNode;
if(nodeTmp)
nodeTmp->nextNode = node;
nodeTmp = node;
if(var == 0)
scaleNodeBegin = node;
}
}
void CharView::MouseWheelUpdateStartEndValue(int flag)
{
double zoomValue = (endScaleValue - startScaleValue)/10;
if(flag > 0)
{
endScaleValue -= zoomValue;
}
else{
endScaleValue += zoomValue;
}
double everyWidthValueOld = everyWidthValue;
double centerX = currentPointF.x() - leftBorder;
everyWidthValue = ((double)(endScaleValue - startScaleValue))/(width() - leftBorder - rightBorder);
startScaleValue = startScaleValue + centerX*everyWidthValueOld - centerX*everyWidthValue ;
endScaleValue = endScaleValue + centerX*everyWidthValueOld - centerX*everyWidthValue ;
if(startScaleValue <=0)
startScaleValue = 0;
}
void CharView::MouseLeftMoveUpdateStartEndValue()
{
double offsetX = currentPointF.x() - pressPointF.x();
pressPointF = currentPointF;
double offsetValue = offsetX*everyWidthValue;
if(startScaleValue - offsetValue <=0 && offsetX > 0){
startScaleValue = 0;
offsetValue = startScaleValue;
}else{
startScaleValue = startScaleValue - offsetValue;
}
endScaleValue = endScaleValue - offsetValue;
}
void CharView::MouseRightMoveUpdateStartEndValue()
{
if(currentPointF.x() < leftBorder || currentPointF.x() > width() - rightBorder ||
pressPointF.x() < leftBorder || pressPointF.x() > width() - rightBorder|| !bPressRight)
return;
endScaleValue = startScaleValue + (currentPointF.x() - leftBorder)*everyWidthValue;
startScaleValue = startScaleValue + (pressPointF.x() - leftBorder)*everyWidthValue;
}
void CharView::paintEvent(QPaintEvent *event)
{
//界面大小改变,只改变刻度实际宽度, 刻度开始结束值不变
//鼠标缩放,刻度实际宽度改变, 刻度开始结束值改变
//鼠标拖动,刻度实际宽度不变, 刻度开始结束值改变
//绘制前计算更新刻度
UpdeScaleNode();
QPainter painter(this);
// painter.setRenderHint(QPainter::Antialiasing);//加上会加粗
//绘制刻度
paintAxisX(painter);
paintAxisY(painter);
//绘制数据
paintData(painter);
paintMouseRightMove(painter);
//绘制游标
if(bShowCursor)
paintCursor(painter);
}
void CharView::paintMouseRightMove(QPainter &painter)
{
if(currentPointF.x() < leftBorder || currentPointF.x() > width() - rightBorder ||
pressPointF.x() < leftBorder || pressPointF.x() > width() - rightBorder|| !bPressRight)
return;
QPen pen;
pen.setStyle(Qt::DashLine);
pen.setColor(QColor(236,132,251));
pen.setWidth(1);
painter.setPen(pen);
double w = currentPointF.x() - pressPointF.x();
double y = currentPointF.y() - pressPointF.y();
painter.drawRect(pressPointF.x(),pressPointF.y(), w, y);
}
void CharView::paintAxisX(QPainter &painter)
{
QPen pen;
pen.setStyle(Qt::SolidLine);
pen.setColor(Qt::black);
pen.setWidth(1);
painter.setPen(pen);
int y = height() - bottomBorder;
painter.drawLine(QPointF(leftBorder, y),
QPointF(width() - rightBorder, y));
ScaleNode* node = scaleNodeBegin;
while(node){
painter.drawLine(node->pointScaleOne,node->pointScaleTwo);
if(node->bShowScaleText)
painter.drawText(node->pointScaleText.x(), node->pointScaleText.y(), scaleTextWidth, scaleTextHeight,
Qt::AlignCenter, QString::number(node->scaleValue, 'f', 0));
node = node->nextNode;
}
}
void CharView::paintAxisY(QPainter &painter)
{
}
void CharView::paintCursor(QPainter &painter)
{
if(currentPointF.x() < leftBorder || currentPointF.x() > width() - rightBorder)
return;
QPen pen;
pen.setStyle(Qt::DashLine);
pen.setColor(QColor(236,132,251));
pen.setWidth(1);
painter.setPen(pen);
painter.drawLine(QPointF(currentPointF.x(), 0), QPointF(currentPointF.x(), height() - bottomBorder));
double number = (currentPointF.x() - leftBorder)*everyWidthValue + startScaleValue;
painter.drawText(currentPointF.x(), height() - bottomBorder - scaleTextHeight, scaleTextWidth, scaleTextHeight,
Qt::AlignLeft, QString::number(number, 'f', 0));
}
void CharView::paintData(QPainter &painter)
{
//test
double value1 = 1240000000;
double value2 = 1590000000;
double x1 = leftBorder + (value1 - startScaleValue)/everyWidthValue;
double x2 = leftBorder + (value2 - startScaleValue)/everyWidthValue;
QPointF point1(x1, 100);
QPointF point2(x2, 200);
QPen pen;
pen.setStyle(Qt::SolidLine);
pen.setColor(Qt::black);
pen.setWidth(1);
painter.setPen(pen);
painter.drawLine(point1,point2);
}
void CharView::resizeEvent(QResizeEvent *event)
{
UpdeScaleNode();
return QWidget::resizeEvent(event);
}
void CharView::mouseMoveEvent(QMouseEvent *event)
{
currentPointF = event->localPos();
if(bPressLeft){
if(currentPointF != pressPointF)
MouseLeftMoveUpdateStartEndValue();
}
else if(bPressRight){
bPressRightMove = true;
}
update();
return QWidget::mouseMoveEvent(event);
}
void CharView::mousePressEvent(QMouseEvent *event)
{
if(!bPressLeft && event->button() == Qt::LeftButton){
bPressLeft = true;
pressPointF = event->localPos();
}
else if(!bPressRight && event->button() == Qt::RightButton){
bPressRight = true;
pressPointF = event->localPos();
}
return QWidget::mousePressEvent(event);
}
void CharView::mouseReleaseEvent(QMouseEvent *event)
{
if(bPressRight)
{
if(bPressRightMove && currentPointF != pressPointF)
MouseRightMoveUpdateStartEndValue();
bPressRight = false;
bPressRightMove = false;
update();
}
bPressLeft = false;
return QWidget::mouseReleaseEvent(event);
}
void CharView::wheelEvent(QWheelEvent *event)
{
MouseWheelUpdateStartEndValue(event->delta());
update();
return QWidget::wheelEvent(event);
}
void CharView::mouseDoubleClickEvent(QMouseEvent *event)
{
startScaleValue = startScaleValueInit;
endScaleValue = endScaleValueInit;
return QWidget::mouseDoubleClickEvent(event);
}