当前位置: 首页 > news >正文

Qt基于paintEvent自定义CharView

Qt基于paintEvent自定义CharView

鼠标拖动,缩放,区域缩放, 针对x轴,直接上代码
请添加图片描述

charview.h

#ifndef CHARVIEW_H
#define CHARVIEW_H#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
#include <QResizeEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QPointF>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;//每多少个刻度显示刻度textdouble 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 <QDebug>
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)
{//testdouble 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);
}

相关文章:

Qt基于paintEvent自定义CharView

Qt基于paintEvent自定义CharView 鼠标拖动&#xff0c;缩放&#xff0c;区域缩放&#xff0c; 针对x轴&#xff0c;直接上代码 charview.h #ifndef CHARVIEW_H #define CHARVIEW_H#include <QWidget> #include <QPainter> #include <QPaintEvent> #inclu…...

Mac FoneLab for Mac:轻松恢复iOS数据,专业工具助力生活

如果你曾经不小心删除了重要的iOS数据&#xff0c;或者因为各种原因丢失了这些数据&#xff0c;那么你一定知道这种痛苦。现在&#xff0c;有一个名为Mac FoneLab的Mac应用程序&#xff0c;它专门设计用于恢复iOS数据&#xff0c;这可能是你的救星。 Mac FoneLab for Mac是一种…...

代码随想录二刷day30

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、力扣332. 重新安排行程二、力扣51. N 皇后三、力扣37. 解数独 一、力扣332. 重新安排行程 class Solution {private LinkedList<String> res;private Li…...

工业检测 ocr

采用OpenCV和深度学习的钢印识别_菲斯奇的博客-CSDN博客采用OpenCV和深度学习的钢印识别[这个帖子标题党了很久&#xff0c;大概9月初立贴&#xff0c;本来以为比较好做&#xff0c;后来有事情耽搁了&#xff0c;直到现在才有了一些拿得出手的东西。肯定不会太监的。好&#xf…...

LVS负载均衡群集

这里写目录标题 LVS负载均衡群集一.集群cluster与分布式1.特点&#xff1a;2.类型1&#xff09;负载均衡群集 LB2&#xff09;高可用群集 HA3&#xff09;高性能运输群集 HPC 3.分布式1&#xff09;特点 二.LVS1.lvs的工作原理2.lvs的三种工作模式1&#xff09;NAT 地址转换2&a…...

安卓截屏;前台服务

private var mediaProjectionManager: MediaProjectionManager? nullval REQUEST_MEDIA_PROJECTION 10001private var isstartservice true//启动MediaService服务fun startMediaService() {if (isstartservice) {startService(Intent(this, MediaService::class.java))iss…...

C++ PrimerPlus 复习 第八章 函数探幽

第一章 命令编译链接文件 make文件 第二章 进入c 第三章 处理数据 第四章 复合类型 &#xff08;上&#xff09; 第四章 复合类型 &#xff08;下&#xff09; 第五章 循环和关系表达式 第六章 分支语句和逻辑运算符 第七章 函数——C的编程模块&#xff08;上&#xff…...

JavaScript-Ajax-axios-Xhr

JS的异步请求 主要有xhr xmlHttpRequest 以及axios 下面给出代码以及详细用法&#xff0c;都写在了注释里 直接拿去用即可 测试中默认的密码为123456 账号admin 其他一律返回登录失败 代码实例 <!DOCTYPE html> <html lang"en"> <head><…...

怎样查看kafka写数据送到topic是否成功

要查看 Kafka 写数据是否成功送到主题&#xff08;topic&#xff09;&#xff0c;可以通过以下几种方法来进行确认&#xff1a; Kafka 生产者确认机制&#xff1a;Kafka 提供了生产者的确认机制&#xff0c;您可以在创建生产者时设置 acks 属性来控制确认级别。常见的确认级别包…...

腾讯mini项目-【指标监控服务重构】2023-08-16

今日已办 v1 验证 StageHandler 在处理消息时是否为单例&#xff0c;【错误尝试】 type StageHandler struct { }func (s StageHandler) Middleware1(h message.HandlerFunc) message.HandlerFunc {return func(msg *message.Message) ([]*message.Message, error) {log.Log…...

PTA:7-3 两个递增链表的差集

^两个递增链表的差集 题目输入样例输出样例 代码 题目 输入样例 5 1 3 5 7 9 3 2 3 5输出样例 3 1 7 9代码 #include <iostream> #include <list> #include <unordered_set> using namespace std; int main() {int n1, n2;cin >> n1;list<int&g…...

智能合约漏洞案例,DEI 漏洞复现

智能合约漏洞案例&#xff0c;DEI 漏洞复现 1. 漏洞简介 https://twitter.com/eugenioclrc/status/1654576296507088906 2. 相关地址或交易 https://explorer.phalcon.xyz/tx/arbitrum/0xb1141785b7b94eb37c39c37f0272744c6e79ca1517529fec3f4af59d4c3c37ef 攻击交易 3. …...

Attention is all you need 论文笔记

该论文引入Transformer&#xff0c;主要核心是自注意力机制&#xff0c;自注意力&#xff08;Self-Attention&#xff09;机制是一种可以考虑输入序列中所有位置信息的机制。 RNN介绍 引入RNN为了更好的处理序列信息&#xff0c;比如我 吃 苹果&#xff0c;前后的输入之间是有…...

Hdoop伪分布式集群搭建

文章目录 Hadoop安装部署前言1.环境2.步骤3.效果图 具体步骤&#xff08;一&#xff09;前期准备&#xff08;1&#xff09;ping外网&#xff08;2&#xff09;配置主机名&#xff08;3&#xff09;配置时钟同步&#xff08;4&#xff09;关闭防火墙 &#xff08;二&#xff09…...

java临时文件

临时文件 有时候&#xff0c;我们程序运行时需要产生中间文件&#xff0c;但是这些文件只是临时用途&#xff0c;并不做长久保存。 我们可以使用临时文件&#xff0c;不需要长久保存。 public static File createTempFile(String prefix, String suffix)prefix 前缀 suffix …...

C++中的<string>头文件 和 <cstring>头文件简介

C中的<string>头文件 和 <cstring>头文件简介 在C中<string> 和 <cstring> 是两个不同的头文件。 <string> 是C标准库中的头文件&#xff0c;定义了一个名为std::string的类&#xff0c;提供了对字符串的操作如size()、length()、empty() 及字…...

安装MySQL

Centos7下安装MySQL详细步骤_centos7安装mysql教程_欢欢李的博客-CSDN博客...

输入学生成绩,函数返回最大元素的数组下标,求最高分学生成绩(输入负数表示输入结束)

scanfscore()函数用于输入学生的成绩 int scanfscore(int score[N])//输入学生的成绩 {int i -1;do {i;printf("输入学生成绩:");scanf("%d", &score[i]);} while (score[i] > 0);return i; } findmax()用于寻找最大值 int findmax(int score[N…...

常用音频接口:TDM,PDM,I2S,PCM

常用音频接口&#xff1a;TDM&#xff0c;PDM&#xff0c;I2S&#xff0c;PCM_tdm音频_沙漠的甲壳虫的博客-CSDN博客 I2S/PCM接口及音频codec_音频pcm接口模块设计-CSDN博客 2个TDM8功放调试ing_周龙(AI湖湘学派)的博客-CSDN博客 数字音频接口时序----IIS、TDM、PCM、PDM_td…...

git clone报错Failed to connect to github.com port 443 after 21055 ms:

git 设置代理端口号 git config --global http.proxy http://127.0.0.1:10085 和 git config --global https.proxy http://127.0.0.1:10085 然后就可以成功git clone hugging face的数据集了 如果是https://huggingface.co/datasets/shibing624/medical/tree/main 那么…...

YOLO12快速部署指南:Gradio界面已配好,启动就能用

YOLO12快速部署指南&#xff1a;Gradio界面已配好&#xff0c;启动就能用 1. 为什么选择YOLO12镜像 YOLO12作为2025年最新发布的目标检测模型&#xff0c;带来了革命性的注意力为中心架构。这个预配置好的镜像让您无需任何复杂操作&#xff0c;就能立即体验最先进的目标检测技…...

Vue3+Element Plus+Sortable.js:构建可定制化表格拖拽配置中心

1. 为什么需要表格拖拽配置中心 后台管理系统中最常见的需求之一就是表格展示数据。但不同用户对表格的展示需求往往不同&#xff1a;产品经理可能更关注日期和状态字段&#xff0c;运营人员则更看重用户行为和转化数据。传统解决方案是开发多个固定表格页面&#xff0c;但这会…...

经典35kW V型磁钢永磁同步电机设计:基于Maxwell的成熟方案解析

基于Maxwell设计的 经典35kW&#xff0c;外径290 轴向长度88 3000RPM&#xff0c;111.5Nm, 6极36槽永磁同步电机&#xff08;PMSM&#xff09;设计案例(V型磁钢)&#xff0c;该案例已制作样机&#xff0c;方案成熟&#xff0c;运行稳定&#xff0c;可直接用于生产&#xff0c…...

3分钟让Windows 11脱胎换骨:Win11Debloat全面系统优化指南

3分钟让Windows 11脱胎换骨&#xff1a;Win11Debloat全面系统优化指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter an…...

Hunyuan模型如何降本增效?1.8B边缘部署实战案例分享

Hunyuan模型如何降本增效&#xff1f;1.8B边缘部署实战案例分享 1. 模型介绍与核心优势 混元翻译模型1.5版本带来了两个重要更新&#xff1a;18亿参数的HY-MT1.5-1.8B和70亿参数的HY-MT1.5-7B。这两个模型都专注于支持33种语言之间的互译&#xff0c;特别包含了5种民族语言及…...

告别电量焦虑:用STM32+IP2366打造你的140W双向快充移动电源方案

告别电量焦虑&#xff1a;用STM32IP2366打造140W双向快充移动电源方案 1. 为什么需要高性能移动电源方案 当代智能设备对电力的需求呈现爆发式增长。从智能手机到笔记本电脑&#xff0c;从无人机到便携式医疗设备&#xff0c;快速充电和大容量储能已成为刚需。传统移动电源方…...

5个Windows运行Android应用方案测评:普通用户的轻量级跨平台解决方案

5个Windows运行Android应用方案测评&#xff1a;普通用户的轻量级跨平台解决方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 在数字化办公与娱乐日益融合的今天&am…...

从下载到运行:Pi0模型完整部署指南,适合新手入门

从下载到运行&#xff1a;Pi0模型完整部署指南&#xff0c;适合新手入门 1. 项目简介&#xff1a;什么是Pi0&#xff1f; Pi0是一个视觉-语言-动作流模型&#xff0c;专门为通用机器人控制设计。简单来说&#xff0c;它能让机器人“看懂”周围环境&#xff0c;“听懂”你的指…...

M2LOrder模型Python爬虫实战:应对动态渲染与数据加密网站

M2LOrder模型Python爬虫实战&#xff1a;应对动态渲染与数据加密网站 最近有个朋友找我帮忙&#xff0c;说他们公司需要从某个网站上抓取一些商品数据&#xff0c;但试了好几个爬虫工具都搞不定。我一看&#xff0c;好家伙&#xff0c;这网站不仅数据是页面加载完才动态生成的…...

Phi-4-mini-reasoning在LSTM时间序列预测中的应用与优化

Phi-4-mini-reasoning在LSTM时间序列预测中的应用与优化 1. 当传统预测遇上智能推理 时间序列预测一直是数据分析领域的经典难题。无论是股票价格波动还是商品销量变化&#xff0c;传统的LSTM模型虽然能捕捉时间依赖关系&#xff0c;但面对突发新闻事件或政策变化时&#xff…...