C++ 绘制画布标尺

news2024/11/28 1:46:06
目标

关键代码

CRulerDrawer::CRulerDrawer(QPainter& painter, QRect rect, int scalePercent)
    : m_painter(painter), m_rect(rect), m_scalePercent(scalePercent)
{
    m_palette = qApp->palette();
    m_scaleUnitSize = PixelRuler::Instance()->GetScaleUnitSize();
}

void CRulerDrawer::Draw(ScaleDirection direction, bool drawText)
{
    switch (direction)
    {
    case CRulerDrawer::Top:
        DrawHorizontalScale(true, drawText);
        break;
    case CRulerDrawer::Bottom:
        DrawHorizontalScale(false, drawText);
        break;
    case CRulerDrawer::Left:
        DrawVerticalScale(true, drawText);
        break;
    case CRulerDrawer::Right:
        DrawVerticalScale(false, drawText);
        break;
    }
}

void CRulerDrawer::DrawHorizontalScale(int top, bool drawText)
{
    m_painter.save();
    //绘制水平标尺
    int x_pos{ 0 };		//水平刻度
    m_painter.setPen(QPen(m_palette.color(QPalette::Text)));
    //绘制刻度

    int y_pos_start;
    if (top)
        y_pos_start = 0;
    else
        y_pos_start = m_rect.height();

    while (DPI(x_pos) <= m_rect.width() - 2 * SCALE_MARGIN)
    {
        int line_length;		//刻度的长度
        if (x_pos % (m_scaleUnitSize * m_scaleUnitSize) == 0)		//刻度值为100的倍数时绘制刻度的长度为10像素
            line_length = DPI(10);
        else if (x_pos % (m_scaleUnitSize * m_scaleUnitSize / 2) == 0)	//刻度值为50的倍数时绘制刻度的长度为8像素
            line_length = DPI(8);
        else
            line_length = DPI(5);
        int y_pos_end;
        if (top)
            y_pos_end = y_pos_start + line_length;
        else
            y_pos_end = y_pos_start - line_length;
        m_painter.drawLine(QPoint(DPI(x_pos) + SCALE_MARGIN - 1, y_pos_start), QPoint(DPI(x_pos) + SCALE_MARGIN - 1, y_pos_end));
        //画刻度上的文本
        if (drawText && x_pos % (m_scaleUnitSize * m_scaleUnitSize) == 0)		//当刻度值为100的倍数时显示刻度值
        {
            QString str = QString::number(x_pos);
            QSize str_size = m_painter.fontMetrics().size(Qt::TextSingleLine, str);
            int y_pos_text;
            if (top)
                y_pos_text = DPI(12);
            else
                y_pos_text = y_pos_start - DPI(12) - str_size.height();
            QRect rect{ QPoint{ DPI(x_pos) + SCALE_MARGIN - str_size.width() / 2, y_pos_text }, str_size };
            m_painter.drawText(rect, str);
        }
        x_pos += m_scaleUnitSize;
    }
    m_painter.restore();
}

void CRulerDrawer::DrawVerticalScale(int left, bool drawText)
{
    m_painter.save();
    //绘制垂直标尺
    int y_pos{ 0 };		//垂直刻度
    m_painter.setPen(QPen(m_palette.color(QPalette::Text)));
    //绘制刻度

    int x_pos_start;
    if (left)
        x_pos_start = 0;
    else
        x_pos_start = m_rect.width();

    while (DPI(y_pos) <= m_rect.height() - 2 * SCALE_MARGIN)
    {
        int line_length;		//刻度的长度
        if (y_pos % (m_scaleUnitSize * m_scaleUnitSize) == 0)		//刻度值为100的倍数时绘制刻度的长度为10像素
            line_length = DPI(10);
        else if (y_pos % (m_scaleUnitSize * m_scaleUnitSize / 2) == 0)	//刻度值为50的倍数时绘制刻度的长度为8像素
            line_length = DPI(8);
        else
            line_length = DPI(5);
        int x_pos_end;
        if (left)
            x_pos_end = x_pos_start + line_length;
        else
            x_pos_end = x_pos_start - line_length;
        m_painter.drawLine(QPoint(x_pos_start, DPI(y_pos) + SCALE_MARGIN - 1), QPoint(x_pos_end, DPI(y_pos) + SCALE_MARGIN - 1));
        //画刻度上的文本
        if (drawText && y_pos % (m_scaleUnitSize * m_scaleUnitSize) == 0)		//当刻度值为100的倍数时显示刻度值
        {
            QString str = QString::number(y_pos);
            QSize str_size = m_painter.fontMetrics().size(Qt::TextSingleLine, str);
            int x_pos_text;
            if (left)
                x_pos_text = DPI(12);
            else
                x_pos_text = x_pos_start - DPI(12) - str_size.width();
            QRect rect{ QPoint{ x_pos_text, DPI(y_pos) + SCALE_MARGIN - str_size.height() / 2 }, str_size };
            m_painter.drawText(rect, str);
        }
        y_pos += m_scaleUnitSize;
    }
    m_painter.restore();
}

int CRulerDrawer::DPI(int pixel)
{
    return pixel * m_scalePercent / 100;
}
效果


创作不易,小小的支持一下吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961730.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JS|第22期】深入理解跨域

日期&#xff1a;2024年7月6日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

Vue开发环境搭建

文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II VUE项目的基础配置2.1 制定不同的环境配置2.2 正式环境隐藏日志2.3 vscode常用插件引言 开发工具: node.js 、npm 开发编辑器:vscode 开发框架:VUE I 安装NVM…

react中zuStand状态管理工具使用

一、zuStand的基本使用 1.安装工具 npm install zustand 2.新建文件 在src下新建store文件夹&#xff0c;在store文件夹下新建zuStand.js文件 3.配置zuStand.js // 1.引入创建方法 import { create } from "zustand";// 2.创建store const useStore create((s…

未来不会使用 AI 的人真的会被淘汰吗?

AI 是今年大火的一个话题&#xff0c;随着 ChatGPT 之类的一系列大模型开始流行以后&#xff0c;有不少的培训机构宣称这样的口号: “未来不会使用 AI 的人将会被淘汰”。我觉得这个观点本身并没有错&#xff0c;但是关键在于那些培训机构出于自身的利益&#xff0c;故意忽略了…

(源码分析)springsecurity认证授权

了解 1. 结构总览 SpringSecurity所解决的问题就是安全访问控制&#xff0c;而安全访问控制功能其实就是对所有进入系统的请求进行拦截&#xff0c;校验每个请求是否能够访问它所期望的资源。 根据前边知识的学习&#xff0c;可以通过Filter或AoP等技术来实现&#xff0c;Spr…

Sparse Vector Coding稀疏矢量码介绍

需要MATLAB代码的小伙伴请通过微信公众号私信我~ 更多精彩内容请关注微信公众号 ‘优化与算法’ 前言 5G和6G无线通信期望带来更高的频谱效率和能量效率&#xff0c;为了达到这些目标&#xff0c;近年来已经提出了各种新技术。其中&#xff0c;索引调制IM&#xff08;Index …

「树形结构」基于 Antd 实现一个动态增加子节点+可拖拽的树

效果 如图所示 实现 import { createRoot } from react-dom/client; import React, { useState } from react; import { Tree, Input, Button } from antd; import { PlusOutlined } from ant-design/icons;const { TreeNode } Tree; const { Search } Input;const ini…

优选算法之位运算

目录 一、常见位运算总结 1.基础位运算 2.给定一个数 n&#xff0c;确定它的二进制表示中的第 x 位是 0 还是 1 3.将一个数 n 的二进制表示的第 x 位修改成1 4.将一个数 n 的二进制表示的第 x 位修改成 0 5.提取一个数 n 二进制表示中最右侧的1 6.干掉一个数 n 二进制表示…

分布式存储系统架构及应用

分布式存储系统概述&#xff08;详细、全面&#xff09; 【摘要】深度剖析分布式存储系统的可靠性、可用性、IO性能、数据存储效率、安全性及管理性&#xff0c;为寻求了解此领域的读者提供实用参考。 一、 内容总括 分布式存储系统&#xff0c;依托网络互联的多节点软硬件协同…

人脸识别又进化:扫一下 我就知道你得了啥病

未来&#xff0c;扫下你的脸&#xff0c;可能就知道你得啥病了。没在瞎掰&#xff0c;最近的一项研究成果&#xff0c;还真让咱看到了一点眉目。北大的一个研究团队&#xff0c;搞出来一个 AI &#xff0c;说是用热成像仪扫一下脸&#xff0c;就能检测出有没有高血压、糖尿病和…

工作纪实54-git使用ssh方式

很多居家的小伙伴要重新clone项目&#xff0c;但是忘记了密码&#xff0c;最恶心的是idea还会自动帮你记录密码&#xff0c;如果输错了&#xff0c;会很恶心&#xff0c;使用ssh则不会&#xff1b;还有一个好处就是&#xff0c;集团的密码一般都是几个月更新一次&#xff0c;ss…

基于Frp搭建Window-Linux内网穿透完整流程

什么是内网穿透? 内网穿透是我们在进行网络连接时的一种术语&#xff0c;也叫做NAT穿透&#xff0c;即在计算机是局域网内的时候&#xff0c;外网与内网的计算机的节点进行连接时所需要的连接通信&#xff0c;有时候就会出现内网穿透不支的情况。内网穿透的功能就是&#xff0…

只出现一次的数字-位运算

题目描述&#xff1a; 个人题解&#xff1a; 代码实现&#xff1a; class Solution { public:int singleNumber(vector<int>& nums) {int ret 0;for (auto e: nums) ret ^ e;return ret;} };复杂度分析&#xff1a; 时间复杂度&#xff1a;O(n)&#xff0c;其中 n…

19018 正则序列

这个问题可以通过排序和计数来解决。首先&#xff0c;我们将数组排序&#xff0c;然后我们遍历排序后的数组&#xff0c;对于每个元素&#xff0c;我们将它变为它应该在正则序列中的值&#xff0c;也就是它的索引加1。我们将这个变化的绝对值累加起来&#xff0c;这就是我们需要…

STM32智能农业灌溉系统教程

目录 引言环境准备智能农业灌溉系统基础代码实现&#xff1a;实现智能农业灌溉系统 4.1 数据采集模块 4.2 数据处理与分析模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;农业监测与优化问题解决方案与优化收尾与总结 1. 引言 智能农业灌溉系统通…

Sklearn实例:水果多分类

机器学习五步&#xff1a; 加载数据集分割数据集建立模型训练模型预测模型 导入库文件 import numpy as np #科学计算库 import matplotlib.pyplot as plt #绘图库可视化函数 import pandas as pd #数据处理库&#xff0c;数据分析库 import seaborn as sns #高级数据可视化…

AI技术修复奥运珍贵历史影像,《永不失色的她》再现百年奥运女性光彩

Greatness of HER &#xff01; AI致敬 , 了不起的「她」。 7月25日&#xff0c;在国际奥委会和各方力量的支持下&#xff0c;阿里云以AI技术修复奥运珍贵历史影像&#xff0c;让百年奥运女性的伟大光彩被看见&#xff0c;并在巴黎推出《永不失色的她》全球首映礼。 国际奥委会…

【练习】使用DevEco Studio编写鸿蒙代码,实现卡片效果,主要是练习布局

效果展示 实现代码 build() {Column(){Column(){Image($r("app.media.avatar")).width("100%").borderRadius({topLeft:10,topRight:10})Text("今晚吃这个 | 每日艺术分享 No.43").fontSize(14).fontWeight(600).lineHeight(22).height(60)Row(…

Xlua原理分析 四

前面已经介绍了Xlua的通信原理&#xff0c;这篇主要记录Xlua如何做到Hotfix的。 我们项目就用到Xlua的Hotfix特性&#xff0c;周更用Lua去修改代码。版本内用C#开发。这点我觉得是Xlua比toLua强大的重要特性之一。 如何使用Hotfix本篇不介绍了&#xff0c;看Xlua教程懂得都懂…