当前位置: 首页 > 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 那么…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...