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 鼠标拖动,缩放,区域缩放, 针对x轴,直接上代码 charview.h #ifndef CHARVIEW_H #define CHARVIEW_H#include <QWidget> #include <QPainter> #include <QPaintEvent> #inclu…...
Mac FoneLab for Mac:轻松恢复iOS数据,专业工具助力生活
如果你曾经不小心删除了重要的iOS数据,或者因为各种原因丢失了这些数据,那么你一定知道这种痛苦。现在,有一个名为Mac FoneLab的Mac应用程序,它专门设计用于恢复iOS数据,这可能是你的救星。 Mac FoneLab for Mac是一种…...
代码随想录二刷day30
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、力扣332. 重新安排行程二、力扣51. N 皇后三、力扣37. 解数独 一、力扣332. 重新安排行程 class Solution {private LinkedList<String> res;private Li…...
工业检测 ocr
采用OpenCV和深度学习的钢印识别_菲斯奇的博客-CSDN博客采用OpenCV和深度学习的钢印识别[这个帖子标题党了很久,大概9月初立贴,本来以为比较好做,后来有事情耽搁了,直到现在才有了一些拿得出手的东西。肯定不会太监的。好…...
LVS负载均衡群集
这里写目录标题 LVS负载均衡群集一.集群cluster与分布式1.特点:2.类型1)负载均衡群集 LB2)高可用群集 HA3)高性能运输群集 HPC 3.分布式1)特点 二.LVS1.lvs的工作原理2.lvs的三种工作模式1)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 第三章 处理数据 第四章 复合类型 (上) 第四章 复合类型 (下) 第五章 循环和关系表达式 第六章 分支语句和逻辑运算符 第七章 函数——C的编程模块(上ÿ…...
JavaScript-Ajax-axios-Xhr
JS的异步请求 主要有xhr xmlHttpRequest 以及axios 下面给出代码以及详细用法,都写在了注释里 直接拿去用即可 测试中默认的密码为123456 账号admin 其他一律返回登录失败 代码实例 <!DOCTYPE html> <html lang"en"> <head><…...
怎样查看kafka写数据送到topic是否成功
要查看 Kafka 写数据是否成功送到主题(topic),可以通过以下几种方法来进行确认: Kafka 生产者确认机制:Kafka 提供了生产者的确认机制,您可以在创建生产者时设置 acks 属性来控制确认级别。常见的确认级别包…...
腾讯mini项目-【指标监控服务重构】2023-08-16
今日已办 v1 验证 StageHandler 在处理消息时是否为单例,【错误尝试】 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 漏洞复现
智能合约漏洞案例,DEI 漏洞复现 1. 漏洞简介 https://twitter.com/eugenioclrc/status/1654576296507088906 2. 相关地址或交易 https://explorer.phalcon.xyz/tx/arbitrum/0xb1141785b7b94eb37c39c37f0272744c6e79ca1517529fec3f4af59d4c3c37ef 攻击交易 3. …...
Attention is all you need 论文笔记
该论文引入Transformer,主要核心是自注意力机制,自注意力(Self-Attention)机制是一种可以考虑输入序列中所有位置信息的机制。 RNN介绍 引入RNN为了更好的处理序列信息,比如我 吃 苹果,前后的输入之间是有…...
Hdoop伪分布式集群搭建
文章目录 Hadoop安装部署前言1.环境2.步骤3.效果图 具体步骤(一)前期准备(1)ping外网(2)配置主机名(3)配置时钟同步(4)关闭防火墙 (二)…...
java临时文件
临时文件 有时候,我们程序运行时需要产生中间文件,但是这些文件只是临时用途,并不做长久保存。 我们可以使用临时文件,不需要长久保存。 public static File createTempFile(String prefix, String suffix)prefix 前缀 suffix …...
C++中的<string>头文件 和 <cstring>头文件简介
C中的<string>头文件 和 <cstring>头文件简介 在C中<string> 和 <cstring> 是两个不同的头文件。 <string> 是C标准库中的头文件,定义了一个名为std::string的类,提供了对字符串的操作如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
常用音频接口:TDM,PDM,I2S,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 那么…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
