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

RWKV7-1.5B-g1a惊艳效果集:120字内专业文案生成、RWKV原理精准科普、摘要无信息丢失

RWKV7-1.5B-g1a惊艳效果集&#xff1a;120字内专业文案生成、RWKV原理精准科普、摘要无信息丢失 1. 模型效果惊艳展示 1.1 专业文案生成能力 RWKV7-1.5B-g1a在120字内的专业文案生成方面表现出色。输入简单提示后&#xff0c;模型能生成符合商业场景的高质量文案&#xff1a…...

Iceoryx(冰羚):无锁队列与并发控制的设计与实现2(源码解析)

接上篇设计3: MpmcLockFreeQueue &#xff08;Multiple Producer Multiple Consumer&#xff09;特点&#xff1a;数据存储与索引分离原理&#xff1a; 当有多个写&#xff0c;需要同时写入数据&#xff0c;那么写入的位置必定发生竞争。写入数据和更改w指针是两步&#xff0c;…...

照着用就行:8个降AIGC网站测评,专科生降AI率必备攻略

在如今的学术写作中&#xff0c;AI生成内容&#xff08;AIGC&#xff09;已经成为许多学生和研究者必须面对的问题。无论是论文初稿还是最终定稿&#xff0c;如何有效降低AI痕迹、避免查重率过高&#xff0c;成为了关键任务。而AI降重工具的出现&#xff0c;正是为了解决这一痛…...

Qwen-Image-2512像素艺术生成实操:调整denoising strength控制像素锐度

Qwen-Image-2512像素艺术生成实操&#xff1a;调整denoising strength控制像素锐度 想用AI生成复古又精致的像素艺术&#xff0c;但总觉得画面糊糊的&#xff0c;不够“像素”&#xff1f;或者线条太锐利&#xff0c;失去了像素艺术特有的“块状”美感&#xff1f;今天&#x…...

5个步骤玩转AntiMicroX:让任何游戏手柄适配PC游戏

5个步骤玩转AntiMicroX&#xff1a;让任何游戏手柄适配PC游戏 【免费下载链接】antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. 项目地址: https://gitcode.com/GitHub_Tr…...

FPGA新手必看:Vivado 2018.3从Verilog代码到比特流下载全流程避坑指南

FPGA开发实战&#xff1a;Vivado 2018.3全流程深度解析与避坑手册 刚接触Xilinx FPGA开发的工程师们&#xff0c;往往会被Vivado这个庞然大物吓到——复杂的界面、繁琐的流程、突如其来的报错&#xff0c;每一步都可能成为项目推进的绊脚石。本文将带你深入Vivado 2018.3的开发…...

云容笔谈·东方红颜影像生成系统与STM32的奇妙联动:在嵌入式设备上展示AI艺术

云容笔谈东方红颜影像生成系统与STM32的奇妙联动&#xff1a;在嵌入式设备上展示AI艺术 你有没有想过&#xff0c;把AI生成的那些精美绝伦的东方美人图&#xff0c;从云端“请”下来&#xff0c;放进一个可以摆在桌面的小相框里&#xff0c;让它成为一件会“呼吸”、能“换装”…...

别再只用Postman了!手把手教你用Chrome插件Talend API Tester搞定接口测试

浏览器端API测试新选择&#xff1a;Talend API Tester深度评测与实战指南 在当今前后端分离的开发模式下&#xff0c;API测试工具已成为开发者日常工作中不可或缺的利器。虽然Postman凭借其丰富的功能长期占据市场主导地位&#xff0c;但对于追求轻量化、即时可用的开发者而言&…...

mPLUG-Owl3-2B与Xshell配合使用:远程开发实战

mPLUG-Owl3-2B与Xshell配合使用&#xff1a;远程开发实战 如果你正在本地电脑上折腾一个像mPLUG-Owl3-2B这样的AI模型&#xff0c;可能会遇到一个头疼的问题&#xff1a;电脑配置不够。模型推理、数据处理&#xff0c;这些任务对内存和算力的要求都不低&#xff0c;自己的笔记…...

ToastFish:如何在Windows通知栏中轻松提升词汇量

ToastFish&#xff1a;如何在Windows通知栏中轻松提升词汇量 【免费下载链接】ToastFish 一个利用摸鱼时间背单词的软件。 项目地址: https://gitcode.com/GitHub_Trending/to/ToastFish 你是否曾在工作间隙想要背几个单词&#xff0c;却又不想被人发现&#xff1f;或者…...