Qt解析含颜色的QString字符串显示到控件

news/2024/5/14 13:01:53/文章来源:https://blog.csdn.net/qq_34414144/article/details/135773718

1、需求

开发接收含颜色字符串显示到窗口,可解析字符串颜色配置窗口属性,且分割字符串显示。
mprintf(“xxxxxx”);打印的xxxxxx含有颜色配置。

2、实现方法

2.1、条件

选用Qt的PlainTextEdit控件显示字符串,配置为只读模式

初始化串口成功后,用下列代码绑定串口信号,收到数据会及时显示

connect(this->serialPort,SIGNAL(readyRead()),this,SLOT(log_serialread()));/* readyRead()触发,接收到的数据长度是不定长的 */
/* log_serialread()是自己实现的接收函数 */
2.2、颜色配置函数

颜色规则参考链接: ANSI控制码

void logThread::display_config(const QString &text)
{QTextCharFormat fmt;QMap<QString, int> map; //颜色列表map["black"] = 30;  //背景色40map["red"] = 31;    //背景色41map["green"] = 32;  //背景色42map["yellow"] = 33; //背景色43map["blue"] = 34;   //背景色44map["magenta"] = 35;//背景色45map["cyan"] = 36;   //背景色46map["white"] = 37;  //背景色47QString text_style = text;QRegularExpression regex("\x1b\\["); QRegularExpression regex_else("m"); text_style = text_style.remove(regex); //去掉\033[text_style = text_style.remove(regex_else); //去掉mQStringList list = text_style.split(";"); //用;分割属性成列表foreach (QString type, list) {if(type == "0") { //常规文本,清除属性fmt.setForeground(QBrush(QColor("black")));fmt.setFontWeight(50); //取消加粗fmt.setFontUnderline(false); //取消下划线}else if(type == "1") { //加粗文本fmt.setFontWeight(63); //63、75、87}else if(type == "4") { //含下划线文件fmt.setFontUnderline(true);}if((type.toInt() >= 30) && (type.toInt() <= 47)){QMap<QString, int>::iterator itor;for (itor = map.begin(); itor != map.end(); ++itor){if(type.toInt() == itor.value()) //30 ~ 37{fmt.setForeground(QBrush(QColor(itor.key()))); //字体色}else if((type.toInt() - 10) == itor.value()) //40 ~ 47{fmt.setBackground(QBrush(QColor(itor.key()))); //背景色}}}}this->printlog_displayPlainTextEdit->mergeCurrentCharFormat(fmt);
}
2.3、log显示函数
void logThread::log_display(const QString &text)
{QString text_in = text;text_in = text_in.remove(QRegularExpression("\\r")); //去掉\r,会当做换行#if 0//将获取的数据追加在文本编辑的末尾,会导致插入的文本换行,显示会乱this->displayPlainTextEdit->appendPlainText(text_in);#else//虽然配置为只读,如果鼠标移动了光标,会导致当前这段数据跳到光标处显示this->displayPlainTextEdit->insertPlainText(text_in); //当前光标位置显示this->displayPlainTextEdit->moveCursor(QTextCursor::End,QTextCursor::MoveAnchor); //移动光标到最后#endif
}
2.4、log接收函数

3种情况的处理规则如图:

在这里插入图片描述

代码实现:

void logThread::log_serialread()
{static QString str;int config_flag = 0;/* 每一次readyRead()触发,都把数据读完,长度不定长*/QString buf = QString(this->serialPort->readAll());int string_length = buf.length();if(!save_str.isEmpty()) //上一次存储的字符串不为空{buf = save_str + buf; //拼接到当前字符串前string_length = buf.length();save_str = ""; //清除存储的字符串       }QRegularExpression re_esc("\x1b"); //匹配颜色标志\033QRegularExpressionMatchIterator j = re_esc.globalMatch(buf); //运用迭代器,可获取每个\033的位置int count_esc = 0;int last_esc_index = 0;while (j.hasNext()) //是否有下一个匹配结果{count_esc++; //统计\033的个数QRegularExpressionMatch match = j.next();; //next()指针往后移动1if(!(j.hasNext())) //无下一个匹配结果,记录最后一个\033的位置{last_esc_index = match.capturedStart();}}QRegularExpression re("\x1b\\[[0-9;]*[mGKF]"); //匹配完整颜色配置QRegularExpressionMatchIterator i = re.globalMatch(buf);QRegularExpressionMatch match_before;int count = 0; while (i.hasNext()) {config_flag = 1; //标志按照颜色配置分割字符串显示count++; //统计完整颜色配置的个数QRegularExpressionMatch match = i.next(); //next()指针往后移动1if(count == 1) //取第一个完整颜色标签之前的文字显示{if(match.capturedStart() != 0){//buf.left()表示从下标0往后,分割match.capturedStart()个字符this->log_display(buf.left(match.capturedStart()));}}else //取上一个标签和当前标签之间字符串显示{   //先按上一个标签配置颜色this->display_config(match_before.captured());//buf.mid()从下标match_before.capturedEnd()往后,分割match.capturedStart() - match_before.capturedEnd()个字符this->log_display(buf.mid(match_before.capturedEnd(), match.capturedStart() - match_before.capturedEnd()));}if(!(i.hasNext())) //无下一个匹配结果{//按当前标签配置颜色this->display_config(match.captured());if(count_esc != count) //完整颜色标签和\033个数不一样{//取当前标签和最后的\033之间字符串显示this->log_display(buf.mid(match.capturedEnd(), last_esc_index - match.capturedEnd()));//存储不完整颜色标签(最后\033及之后的字符串)save_str = buf.right(string_length - last_esc_index);}else{//取末尾标签后面的所有内容显示this->log_display(buf.right(string_length - match.capturedEnd()));}}else //有下一个匹配,存储当前的{match_before = match; }}if(!config_flag){this->log_display(buf);}
}
2.5、显示结果

log内容:

mprintf("\033[1;31mhello\033[0;31m\n"); //1;31m表示红色加粗,0;31m表示红色和取消加粗
mprintf("world\n");
mprintf("\033[32mhello hello\033[0m\n"); //32m表示绿色,0m表示取消颜色
mprintf("world world\n");
mprintf("\033[1;33mhello hello hello\033[0m\n"); //1;33m表示黄色加粗
mprintf("world world world\n");
mprintf("\033[34mhello hello hello hello\033[0;34m\n"); //34m表示蓝色
mprintf("world world world world\n");
mprintf("\033[35mhello hello hello hello hello\033[0;35m\n"); //35m表示紫色
mprintf("world world world world world\n");
mprintf("\033[1;36mhello hello hello hello hello hello\033[0m\n"); //36m表示青色
mprintf("world world world world world world\n");
mprintf("\033[37mhello hello hello hello hello hello hello\033[0;37m\n"); //37m表示白色
mprintf("world world world world world world world\n");

显示结果:

在这里插入图片描述

3、注意事项

“ \t ” 即table,直接送到显示,可能是默认的10多个空格,显示不是很好看,验证配置为8个空格可以对齐。

//设置制表符\t为8个空格
QFontMetrics metrics(this->printlog_displayPlainTextEdit->font());
int tabStopWidth = 8 * metrics.width(' ');
this->printlog_displayPlainTextEdit->setTabStopDistance(tabStopWidth);

“ \r ” 即为enter,直接送到显示,会换行,不需要多余的换行,可以用下列方法去掉。

QString text_in = "\r\n你好\r\n";
text_in = text_in.remove(QRegularExpression("\\r")); //去掉\r,会当做换行

new一个新的QSerialPort()前,一定要检查指针是否为空,关闭串口delete时,一定要将指针置为空,不然程序闪退。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

8. UE5 RPG创建UI(上)

UI是显示角色的一部分属性玩家可以直接查看的界面&#xff0c;通过直观的形式在屏幕上显示角色的各种信息。如何使用一种可扩展&#xff0c;可维护的形式来制作&#xff0c;这不得不说到耳熟能详的MVC架构。 MVC&#xff08;Model-View-Controller&#xff09;是一种常见的软件…

PGSQL安装PostGIS扩展模块

一、PostGIS简介 1、PostGIS介绍 PostGIS是一个空间数据库&#xff0c;空间数据库像存储和操作数据库中其他任何对象一样去存储和操作空间对象。 空间数据与数据库关联起来的三个要素&#xff1a;数据类型、索引和函数。 空间数据类型&#xff1a;用于指定图形为点&#xff0…

css实现扫码循环扫描特效

开发过程中总会遇到不常见的需求&#xff0c;移动端扫描图片加个特效&#xff0c;这里记录一下实现场景 <!DOCTYPE html> <html><head><mate charset"UTF-8"/><title>扫描特效</title><style type"text/css">…

android使用相机 intent.resolveActivity returns null

问题 笔者使用java进行android开发&#xff0c;启动相机时 intent.resolveActivity returns null takePictureIntent.resolveActivity(getPackageManager()) null详细问题 笔者使用如下代码启动相机 // 启动相机SuppressLint("LongLogTag")private void dispatc…

缓激肽(Bradykinin) ELISA kit

灵敏可靠的ELISA试剂盒&#xff0c;用于检测血浆、血清和尿液样本中的缓激肽 缓激肽&#xff08;Bradykinin&#xff09;于1949年被发现&#xff0c;由血浆中的球蛋白前体在蛋白酶的作用下生成。它的名字表明它会促使肠道缓慢运动。早在1909年&#xff0c;人们就注意到在尿液中…

[N-130]基于springboot,vue校园社团管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis-plus 本系…

第一节——单片机概述

1.MCD-51单片机 与8051&#xff08;80C51&#xff09; 兼容的主要产品 ATMEL公司生产的兼容51单片机的具体型号 2.AVR系列单片机 AVR系列是1997年ATMEL公司挪威设计中心的A先生与V先生共同研发出的精简指令集(RISC—Reduced Instruction Set Computer)的高速8位单片机&#xf…

一键拥有你的GPT4

这几天我一直在帮朋友升级ChatGPT&#xff0c;现在已经可以闭眼操作了哈哈&#x1f61d;。我原本以为大家都已经用上GPT4&#xff0c;享受着它带来的巨大帮助时&#xff0c;但结果还挺让我吃惊的&#xff0c;还是有很多人仍苦于如何进行升级。所以就想着写篇教程来教会大家如何…

网络安全---防御保护--子接口小实验

子接口小实验&#xff1a; 环境准备&#xff1a; 防火墙区域配置为trust&#xff1a; PC设置其ip为同一个网段&#xff1a; 此时尝试ping无法ping通的原因是没有打开防火墙允许ping&#xff0c;我们在图形化界面允许ping即可 最终结果&#xff1a; .com域名服务器&#xff1a; …

Redis 笔记二

概览 1.高并发秒杀问题及可能出现的bug 2.秒杀场景JVM级别锁和分布式锁 3.大厂分布式锁Redisson框架 4.从Redisson源码剖析lua解决锁原子性问题 5.从Redisson源码剖析经典锁续命问题 6.Redis主从架构锁失效如何解决 7.Redlock分布式锁高并发下可能存在的问题 8.双十一大促如何将…

电脑加固态硬盘有什么好处

电脑加固态硬盘有很多好处&#xff0c;以下是一些主要的优点&#xff1a; 1. 启动速度更快&#xff1a;固态硬盘&#xff08;SSD&#xff09;的启动速度比传统机械硬盘&#xff08;HDD&#xff09;快得多。这是因为固态硬盘没有旋转部件&#xff0c;而传统硬盘的读写头需要不断…

集简云新增邮件发送功能,适用多种创意场景并提升邮件发送效率

在数字营销中&#xff0c;电子邮件依旧是连接企业与客户的重要桥梁。集简云深知这一点&#xff0c;本周推出为企业通讯打造的内置应用——集简云邮件发送&#xff0c;帮助用户创建充满个性化的交易电子邮件&#xff0c;还能通过HTML自定义代码来实现用户的创意场景。可与近千款…

Linux安装字体

Linux安装字体 一、 上传安装包 fontconfig ttmkfdir二、安装三、安装完成 一、 上传安装包 fontconfig ttmkfdir 上传安装包/opt/ztfonts mkdir /opt/ztfonts cd /opt/ztfonts 二、安装 mkdir -p /usr/share/fonts/chinese #上传字体&#xff0c;按实际需要来 chmod -R 75…

数字图像处理(实践篇)二十六 使用cvlib进行人脸检测、性别检测和目标检测

目录 1 安装cvlib 2 涉及的函数 3 实践 4 其他 cvlib一个简单,高级,易于使用的开源Python计算机视觉库。 1 安装cvlib # 安装依赖pip install opencv-python tensorflow# 安装cvlibpip install cvlib</

【算法专题】动态规划之路径问题

动态规划2.0 动态规划 - - - 路径问题1. 不同路径2. 不同路径Ⅱ3. 珠宝的最高价值4. 下降路径最小和5. 最小路径和6. 地下城游戏 动态规划 - - - 路径问题 1. 不同路径 题目链接 -> Leetcode -62.不同路径 Leetcode -62.不同路径 题目&#xff1a;一个机器人位于一个 m …

【产品交互】超全面B端设计规范总结

不知不觉已经深耕在B端这个领域3年有余&#xff0c;很多人接触过B端后会觉得乏味&#xff0c;因为B端的设计在视觉上并没有C端那么有冲击力&#xff0c;更多的是结合业务逻辑&#xff0c;设计出符合业务需求的交互&#xff0c;以及界面排版的合理性&#xff0c;达到产品的可用性…

新年钜惠|泰迪智能科技免费协助企业完成3个行业AI案例建模

在新年到来之际&#xff0c;为了感谢各企业一直以来对泰迪智能科技的支持&#xff0c;日前我们推出了新年钜惠活动即&#xff1a;免费协助企业完成3个行业AI案例建模。我们希望通过这样的活动&#xff0c;可以帮助更多的企业迈出AI应用的第一步&#xff0c;同时我们也希望能够为…

基于若依的ruoyi-nbcio流程管理系统一种简单的动态表单模拟测试实现(四)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/n…

【AI视野·今日Robot 机器人论文速览 第七十五期】Thu, 11 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Thu, 11 Jan 2024 Totally 16 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Analytical Model and Experimental Testing of the SoftFoot: an Adaptive Robot Foot for Walking over Obstacles and Irre…

文件包含技术总结

开发人员一般会把重复使用的函数写到单个文件中&#xff0c;需要使用某个函数时直接调用此文件&#xff0c;而无需再次编写&#xff0c;这中文件调用的过程一般被称为文件包含。 allow_url_fopen On&#xff08;是否允许打开远程文件&#xff09; allow_url_include On&…