笔记|Qt之画刻度尺入门

Qt之画刻度尺入门 效果图
笔记|Qt之画刻度尺入门
文章图片

上源码

#include "rulerslider.h" #include "QPainter" #include "math.h"#include #include #include RulerSlider::RulerSlider(QWidget *parent):QSlider(parent){//注册过滤器installEventFilter(this); //鼠标事件追踪setMouseTracking(true); //显示当前值labelvalueLabel = new QLabel(this); valueLabel->setStyleSheet("background-color: rgb(0, 0, 0); font-size:14px; color:white; border:1px solid black"); valueLabel->setAlignment(Qt::AlignCenter); valueLabel->hide(); //滑块handleLabel = new QLabel(this); handleLabel->setFixedSize(20,15); handleLabel->raise(); QImage image,result; image.load(":/images/handle.png"); //temppath为图片的路径result = image.scaled(handleLabel->width(), handleLabel->height(),Qt::IgnoreAspectRatio, Qt::SmoothTransformation); //放缩图片,以固定大小显示handleLabel->setPixmap(QPixmap::fromImage(result)); //在Label控件上显示图片}RulerSlider::~RulerSlider(){}/*** 绘制* @brief RulerSlider::paintEvent*/void RulerSlider::paintEvent(QPaintEvent *){QPainter painter; painter.begin(this); //抗锯齿painter.setRenderHint(QPainter::Antialiasing); drawRulerBackgroud(&painter); drawSliderMark(&painter); painter.end(); }/*** 绘制尺子背景* @brief RulerSlider::drawRulerBackgroud* @param painter*/void RulerSlider::drawRulerBackgroud(QPainter *painter){QPointF topLeftPot3(0,0); QPointF bottomRightPot3(width(),height()); painter->setPen(Qt::white); painter->setBrush(QColor(61,84,110)); painter->drawRect(QRectF(topLeftPot3,bottomRightPot3)); }/*** 绘制刻度与值* @brief RulerSlider::drawSliderMark* @param painter*/void RulerSlider::drawSliderMark(QPainter *painter){painter->setPen(Qt::gray); painter->setBrush(QColor(128,128,128)); //计算刻度之间的间隔最小为10int dis = maximum()-minimum(); //绘制横坐标开始起点qreal startX = SIDEDISTANCE; // for (uint16_t i=minimum(); i<=(minimum()+dis/singleStep()); i++) {for (uint16_t i=minimum(); i<=1000; i++) {//偶数if(i%2 == 0 && i%5 == 0){painter->drawRect(QRectF(startX,0,0.1,BIG_Y)); //绘制刻度值float value = https://www.it610.com/article/round(minimum()+((i-minimum())*singleStep())); QString strValue = tr("%1").arg(value); int fontWidth = fontMetrics().width(strValue)/2; painter->drawText(QPointF(startX-fontWidth,BIG_Y+15),strValue); }else {if(i%5 == 0){painter->drawRect(QRectF(startX,0,0.1,MIDDLE_Y)); }else{painter->drawRect(QRectF(startX,0,0.1,SMALL_Y)); }}startX+=sliderInterval; }}/*** 根据鼠标位置获取当前值* @brief RulerSlider::eventPosGetValue* @param ev*/void RulerSlider::eventPosGetValue(QMouseEvent *ev){//光标所在矩形范围double posWidth = (double)width()-SIDEDISTANCER-SIDEDISTANCE; //鼠标光标位置double xpos = ev->pos().x(); if(xpos >=SIDEDISTANCE&&xpos<=width()-SIDEDISTANCER){//根据光标计算double posValue = https://www.it610.com/article/(xpos-SIDEDISTANCE)/posWidth; int value =round(posValue * (maximum()-minimum()) + minimum()); handleLabel->move(xpos-handleLabel->width()/2,0); qDebug()<<"结果值"<minNum){int dis = maxNum-minNum; sliderInterval = (float)(width()-SIDEDISTANCE-SIDEDISTANCER)/(dis/singleStep()); double pos = ((value()-minNum)/singleStep())*sliderInterval+SIDEDISTANCE; handleLabel->move(pos-handleLabel->width()/2,0); }else {handleLabel->move(SIDEDISTANCE-handleLabel->width()/2,0); }update(); }/*** 设置当前值* @brief RulerSlider::setRulerSliderValue* @param value*/void RulerSlider::setRulerSliderValue(int value){int dis = maximum()-minimum(); sliderInterval = (float)(width()-SIDEDISTANCE-SIDEDISTANCER)/(dis/singleStep()); double pos = ((value-minimum())/singleStep())*sliderInterval+SIDEDISTANCE; handleLabel->move(pos-handleLabel->width()/2,0); setValue(value); }/*** 鼠标移动事件* 当mouseIsClick为true时拖动false悬停* @brief RulerSlider::mouseFilterEvent* @param event*/void RulerSlider::mouseFilterEvent(QMouseEvent *event){//鼠标光标位置double xpos = event->pos().x(); if(xpos >=SIDEDISTANCE&&xpos<=width()-SIDEDISTANCER){if(mouseIsClick){handleLabel->move(xpos-handleLabel->width()/2,0); if(valueLabel->isVisible()){valueLabel->hide(); }}else {//光标所在矩形范围double posWidth = (double)width()-SIDEDISTANCER-SIDEDISTANCE; //根据光标计算double posValue = https://www.it610.com/article/(xpos-SIDEDISTANCE)/posWidth; int value =round(posValue * (maximum()-minimum()) + minimum()); if(valueLabel->isHidden()){valueLabel->show(); }if(value >= minimum() && value <= maximum()){valueLabel->setText(QString::number(value)); valueLabel->adjustSize(); valueLabel->move(xpos+DISTANCEMOUSE,height()-valueLabel->height()); valueLabel->raise(); }}}}/*** 事件过滤* @brief RulerSlider::eventFilter* @param watched* @param event* @return*/bool RulerSlider::eventFilter(QObject *watched, QEvent *event){//鼠标事件QMouseEvent *mouseEvent = static_cast(event); //鼠标离开if(QEvent::HoverLeave == event->type()&&!valueLabel->isHidden()){valueLabel->hide(); }//鼠标悬停与拖动if(QEvent::HoverMove == event->type()){mouseFilterEvent(mouseEvent); }//鼠标点击事件if(QEvent::MouseButtonPress == event->type()){if(mouseEvent->button() & Qt::LeftButton){mouseIsClick = true; }}//鼠标释放事件if(QEvent::MouseButtonRelease == event->type()){//注意应先调用父类的鼠标点击处理事件,这样可以不影响拖动的情况QSlider::mouseReleaseEvent(mouseEvent); eventPosGetValue(mouseEvent); mouseIsClick = false; }return QSlider::eventFilter(watched,event); }

.h文件
#ifndef RULERSLIDER_H #define RULERSLIDER_H#define SMALL_Y 5 //小刻度 #define MIDDLE_Y 7 //中刻度 #define BIG_Y 10//大刻度 #define DIFFERVALUE 1 //最小差值(最大值与最小值的差) #define SIDEDISTANCE 10 //尺子距离左边的距离 #define SIDEDISTANCER 50 //尺子距离右边的距离 #define HANDLEWIDTH 10 //滑块的宽度 #define HANDLEHEIGHT 15 //滑块的高度 #define MININTERVSL 10 //最小刻度之间距离 #define MAXINTERVSL 20 //最大刻度之间距离 #define DISTANCEMOUSE 20 //鼠标悬停距离箭头的位置 #include #include class RulerSlider : public QSlider{public:RulerSlider(QWidget *parent = nullptr); ~RulerSlider(); //刻度之间的距离qreal sliderInterval = 1; //显示刻度值QLabel *valueLabel; //滑块QLabel *handleLabel; //鼠标是否点击bool mouseIsClick = false; //设置控件的范围void setRulerSliderRange(int min,int max); //设置当前值void setRulerSliderValue(int value); private://绘制尺子背景void drawRulerBackgroud(QPainter *painter); //绘制刻度线与值void drawSliderMark(QPainter *painter); //根据坐标位置计算当前值void eventPosGetValue(QMouseEvent *ev); //鼠标事件void mouseFilterEvent(QMouseEvent *event); protected://重新绘制void paintEvent(QPaintEvent *); //过滤器bool eventFilter(QObject *watched,QEvent *event); }; #endif // RULERSLIDER_H

【笔记|Qt之画刻度尺入门】widget.cpp文件的
#include "widget.h" #include "ui_widget.h" #include "rulerslider.h" #include Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) {ui->setupUi(this); this->setWindowTitle("Ruler Measurement Tools 2020.08.22 Design By Johnson"); RulerSlider *slider = new RulerSlider(this); slider->setFixedSize(this->width(),300); slider->setSingleStep(1); slider->setRulerSliderRange(0,280); slider->setRulerSliderValue(50); QObject::connect(slider,SIGNAL(valueChanged(int)),this,SLOT(sliderValueChanged(int))); }Widget::~Widget() {delete ui; }void Widget::on_pushButton_clicked() {QMessageBox::aboutQt(this,"about"); }void Widget::on_pushButton_2_clicked() {QMessageBox::warning(this,"软件架构构想","本软件的设计灵感来源于手机端尺子,此软件的开发,将彻底改变用传统实体尺子测量,继而使用电子版测量,永不坏掉,永不丢掉,一次开发,一劳永逸!2020.08.22 Design By Johnson"); }

    推荐阅读