QT自定义控件之内嵌报表(4)(源码开源)

一、前言

在桌面软件开发中,经常会遇到报告、单据、检测报表类界面渲染需求。很多学者第一反应是用 QWidget 堆控件、QTableWidget 做表格,但在做高定制化科技风、工业风报告的时候,控件的边框、渐变背景、霓虹灯质感、自定义表头样式会非常难调,控件组合很容易出现排版错位、样式不统一的问题。

这时候,QPainter直接绘图就成了最优解。现在有了AI的加持,我们可以摆脱控件布局的限制,可以自由实现赛博科技感、深色霓虹边框、渐变文字等 UI 效果。

本文基于 C++ + Qt,使用 QPainter 完整复刻一份肿瘤标志物检测报告界面,实现标题栏、个人信息区、带分割线的检测表格、底部提示栏全套效果。可以给大家提供领高,同时如果有适配性项目也可以直接迁移到医疗检测系统、工业检测软件的报告打印 / 预览模块。

重要说明:本界面仅为 UI 技术演示,不代表真实医疗报告,医疗报告需要遵循医疗机构规范。

二、作品展示

先来上作品

最终实现效果如上图:深色科技网格背景,青蓝色霓虹发光边框,大标题 + 英文副标题;

  • 顶部区域:姓名、年龄、检测日期、报告编号、实验室信息文本排版;

  • 中间核心模块:带圆角外框的 "检测数据" 模块,内部绘制完整表格,包含项目、缩写、结果、参考范围、单位、评估六列表格;

  • 表格内填充肿瘤标志物检测项目(CEA、AFP、CA125、CA199、β2‑MG、HE4)以及对应参考范围与单位;

  • 底部提示栏:圆角提示框,输出免责重要提示文本; 整体配色深色底色 + 青蓝科技色调,模拟数字检验中心的数字化报告风格,AI背景图层+ QPainter 绘制,不使用 QTableWidget 等控件。

    项目创意点

    1、放弃传统控件,QPainter+AI背景实现报表

    传统做法用 QTableWidget,很难实现圆角发光外框、渐变边框效果。
    2、科技深色 UI 配色体系

    整体采用深色底色,搭配青蓝色科技主题色,区分标题文字、表头背景、表格行背景、提示栏背景。表头使用渐变填充,表格奇偶行可以扩展做颜色区分,非常适合医疗、工业检测类软件风格。

    3、表格通用绘制逻辑,可复用

    封装表格绘制函数,传入表头数组、数据数组、单元格宽高,即可自动绘制网格、填充文字。

    4、文本多区域分区排版

    页面划分为:标题区、个人信息区、表格组件区、底部提示区。不同区域坐标隔离,后续修改某一块内容,不会干扰其他区域,方便迭代。

三、实现流程

1、主窗口MainWindow

复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    timer = new QTimer();  // 创建定时器对象
     connect(timer,SIGNAL(timeout()),this,SLOT(SlotTimer()));
}

2、核心代码

主要在CustomWidget.cpp中

复制代码
//绘制文本
void DrawText(QPainter &painter,const QRectF &rect,QString str,double angle,int size,QString fontFamily,int textAlignment)
{
QRectF rotatedRect(-rect.width()/2, -rect.height()/2, rect.width(), rect.height());
qreal cx = rect.x() + rect.width() / 2;
qreal cy = rect.y() + rect.height() / 2;
QFont font = QFont(fontFamily, size);
painter.setFont(font);
painter.save();
painter.translate(cx, cy);
painter.scale(1, -1);
painter.rotate(-angle);
painter.drawText(rotatedRect,textAlignment,str);
painter.restore();
}
//绘制图片
void DrawImage(QPainter &painter, QImage &image, const QRectF &rect,double angle)
{
QRectF rotatedRect(-rect.width()/2, -rect.height()/2, rect.width(), rect.height());
qreal cx = rect.x() + rect.width() / 2;
qreal cy = rect.y() + rect.height() / 2;
painter.save();
painter.translate(cx, cy);
painter.rotate(angle);
painter.drawImage(rotatedRect, image);
painter.restore();
}
//绘制矩形
void rotateAndPaintRect(QPainter *painter, const QRectF &rect, int angle,bool isRound = false,int rx = 0,int ry = 0)
{
qreal cx = 0;
qreal cy = 0;
cx = rect.center().x();
cy = rect.center().y();
painter->save();
painter->translate(cx ,cy);
painter->rotate(angle);
QPointF drawOffset = rect.topLeft() - QPointF(cx,cy);
painter->drawRect(drawOffset.x(), drawOffset.y(), rect.width(), rect.height());
painter->restore();
}

四、源码开放

本期源码开放,有需要的朋友可以去下面位置找我~

QT自定义控件之内嵌报表(4)(源码开源)

相关推荐
浪子明X5 小时前
十六位账本怎样发现传输差错:Internet Checksum 生活类比
开发语言
Quz6 小时前
QML StackView:实现卡片堆叠效果
qt
Quz6 小时前
QML Drawer 抽屉导航详解
qt
xiangyun618 小时前
【408数据结构 08】队列:循环队列判空判满,408年年考,一次讲清
c语言·开发语言·数据结构·c++·算法
xiangyun618 小时前
【408数据结构 06】双链表、循环链表、静态链表
c语言·开发语言·数据结构·c++·算法
白远山9 小时前
家政服务家政社区派单实战:调度系统架构设计与实现指南
java·开发语言·小程序·架构·需求分析
DevRay10 小时前
Java 21虚拟线程深度实战:告别线程池焦虑,百万并发吞吐量直接翻倍(原理+代码+避坑)
java·开发语言
free-elcmacom10 小时前
C++学习<1>程序分区
开发语言·c++
醉颜凉10 小时前
Java 必看:如何彻底避免 HashMap 多线程死循环问题?
java·开发语言
默 语10 小时前
Java新手入门:从零开始安装JDK并配置环境变量
java·开发语言·python·mysql·group by·1024程序员节·数据去重