QT中窗口自绘制效果展示

项目中需要使用QT进行窗口自绘,前期先做一下技术探索,参考相关资料代码熟悉流程。本着代码是最好的老师原则,在此记录一下。

目录

1.运行效果

2.代码结构

3.具体代码


1.运行效果

2.代码结构

3.具体代码

myspeed.pro

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++17# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \drawdialog.cpp \main.cpp \meter1.cpp \meter2.cppHEADERS += \drawdialog.h \meter1.h \meter2.h# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

drawdialog.h

#include <QDialog>class DrawDialog : public QDialog
{Q_OBJECTpublic:explicit DrawDialog(QWidget *parent = 0);void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void paintEvent(QPaintEvent *event) ;void keyPressEvent( QKeyEvent * event );
private:QPoint m_CurrentPos;
};

meter1.h

#ifndef METER1_H
#define METER1_H#include <QWidget>
#include <QMouseEvent>// 仪表盘开发参考博客
// https://blog.csdn.net/yyz_1987/article/details/126958420#comments_29151980
class MyMeter1 : public QWidget
{Q_OBJECTpublic:MyMeter1(QWidget *parent = 0);~MyMeter1();void setValue(double val);protected:void paintEvent(QPaintEvent *);void drawCrown(QPainter *painter);void drawBackground(QPainter *painter);void drawScale(QPainter *painter);void drawScaleNum(QPainter *painter);void drawTitle(QPainter *painter);void drawIndicator(QPainter *painter);void drawNumericValue(QPainter *painter);protected:void mouseMoveEvent(QMouseEvent *event);void mousePressEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);private:QPoint mousePoint;bool mouse_press;private:QColor m_background;QColor m_foreground;int m_maxValue;int m_minValue;int m_startAngle;int m_endAngle;int m_scaleMajor;int m_scaleMinor;double m_value;int m_precision;QTimer *m_updateTimer;QString m_units;QString m_title;public Q_SLOTS:void UpdateAngle();private:};#endif // METER1_H

meter2.h

#ifndef METER2_H
#define METER2_H#include <QWidget>class MyMeter2 : public QWidget
{Q_OBJECTpublic:MyMeter2(QWidget *parent = nullptr);~MyMeter2();void paintEvent(QPaintEvent *event);void timerEvent(QTimerEvent *e);private:void drawFrame(QPainter *painter);void drawScale(QPainter *painter);void drawScaleNum(QPainter *painter);void drawPointer(QPainter *painter);void drawSpeed(QPainter *painter);void drawUnit(QPainter *painter);int speed;int time_id;int status;qreal m_angle;QColor m_foreground;int m_maxValue;int m_minValue;int m_startAngle;int m_endAngle;int m_scaleMajor;int m_scaleMinor;double m_value;int m_precision;//QTimer *m_updateTimer;QString m_units;QString m_title;};
#endif // METER2_H

drawdialog.cpp

#include "drawdialog.h"
#include <QWidget>
#include <QMouseEvent>
#include <QPainter>DrawDialog::DrawDialog(QWidget *parent) : QDialog(parent){//让程序无边框setWindowFlags( Qt::FramelessWindowHint );//让程序背景透明setAttribute(Qt::WA_TranslucentBackground, true);
}void DrawDialog::mousePressEvent(QMouseEvent *event)
{//当鼠标左键按下时,记录当前位置if(event->button() == Qt::LeftButton){m_CurrentPos = event->globalPos() - frameGeometry().topLeft();event->accept();}QDialog::mousePressEvent(event);
}void DrawDialog::mouseMoveEvent(QMouseEvent *event)
{//支持窗体移动if (event->buttons() & Qt::LeftButton){move(event->globalPos() - m_CurrentPos);event->accept();}QDialog::mouseMoveEvent(event);}//绘制图形void DrawDialog::paintEvent(QPaintEvent *event){QPainter painter(this);//反走样painter.setRenderHint(QPainter::Antialiasing,true);painter.setPen( QPen(Qt::green, 2) );painter.setBrush( Qt::blue );QRect rect(10,10,200,260);//绘制一个椭圆painter.drawEllipse(rect);}void DrawDialog::keyPressEvent( QKeyEvent * event )
{//按下esc键时,关闭if(event->key() == Qt::Key_Escape){close();}
}

meter1.cpp

#include "meter1.h"#include <QPainter>// 构造函数
MyMeter1::MyMeter1(QWidget *parent){m_background = Qt::black;m_foreground = Qt::white;m_startAngle = 60;m_endAngle = 60;m_scaleMajor = 10;m_minValue = 0;m_maxValue = 100;m_scaleMajor = 10;//分度m_scaleMinor = 10;m_units = "L/min";m_title = "仪表盘";m_precision = 0;m_value = 0;mouse_press = false;setWindowFlags(Qt::FramelessWindowHint);//无窗体setAttribute(Qt::WA_TranslucentBackground);//背景透明resize(500, 500);}MyMeter1::~MyMeter1()
{}void MyMeter1::setValue(double val)
{m_value = val;
}
//绘制表冠
void MyMeter1::drawCrown(QPainter *painter)
{painter->save();int radius = 100;QLinearGradient lg1(0, -radius, 0, radius);lg1.setColorAt(0, Qt::white); //设置渐变的颜色和路径比例lg1.setColorAt(1, Qt::gray); //只是粗略的颜色,具体的可以参考RGB颜色查询对照表painter->setBrush(lg1); // 创建QBrush对象,把这个渐变对象传递进去:painter->setPen(Qt::NoPen); //边框线无色painter->drawEllipse(-radius, -radius, radius << 1, radius << 1);painter->setBrush(m_background = Qt::black);painter->drawEllipse(-92, -92, 184, 184);painter->restore();
}//绘制刻度数字
void MyMeter1::drawScaleNum(QPainter *painter)
{painter->save();painter->setPen(m_foreground);//m_startAngle是起始角度,m_endAngle是结束角度,m_scaleMajor在一个量程中分成的刻度数double startRad = ( 270-m_startAngle) * (3.14 / 180);double deltaRad = (360 - m_startAngle - m_endAngle) * (3.14 / 180) / m_scaleMajor;double sina,cosa;int x, y;QFontMetricsF fm(this->font());double w, h, tmpVal;QString str;for (int i = 0; i <= m_scaleMajor; i++){sina = sin(startRad - i * deltaRad);cosa = cos(startRad - i * deltaRad);tmpVal = 1.0 * i *((m_maxValue - m_minValue) / m_scaleMajor) + m_minValue;// tmpVal = 50;str = QString( "%1" ).arg(tmpVal);  //%1作为占位符   arg()函数比起 sprintf()来是类型安全的w = fm.size(Qt::TextSingleLine,str).width();h = fm.size(Qt::TextSingleLine,str).height();x = 82 * cosa - w / 2;y = -82 * sina + h / 4;painter->drawText(x, y, str); //函数的前两个参数是显示的坐标位置,后一个是显示的内容,是字符类型""}painter->restore();
}// 绘制刻度线
void MyMeter1::drawScale(QPainter *painter) //绘制刻度线
{painter->save();painter->rotate(m_startAngle);int steps = (m_scaleMajor * m_scaleMinor); //相乘后的值是分的份数double angleStep = (360.0 - m_startAngle - m_endAngle) / steps; //每一个份数的角度// painter->setPen(m_foreground); //m_foreground是颜色的设置// QPen pen = painter->pen(); //第一种方法QPen pen ;pen.setColor(Qt::green); //推荐使用第二种方式for (int i = 0; i <= steps; i++){if (i % m_scaleMinor == 0)//整数刻度显示加粗{pen.setWidth(1); //设置线宽painter->setPen(pen); //使用面向对象的思想,把画笔关联上画家。通过画家画出来painter->drawLine(0, 62, 0, 72); //两个参数应该是两个坐标值}else{pen.setWidth(0);painter->setPen(pen);painter->drawLine(0, 67, 0, 72);}painter->rotate(angleStep);}painter->restore();
}void MyMeter1::drawTitle(QPainter *painter)
{painter->save();painter->setPen(m_foreground);//painter->setBrush(m_foreground);QString str(m_title); //显示仪表的功能QFontMetricsF fm(this->font());double w = fm.size(Qt::TextSingleLine,str).width();painter->drawText(-w / 2, -30, str);painter->restore();
}// 显示的单位,与数值
void MyMeter1::drawNumericValue(QPainter *painter)
{QString str = QString("%1 %2").arg(m_value, 0, 'f', m_precision).arg(m_units);QFontMetricsF fm(font());double w = fm.size(Qt::TextSingleLine,str).width();painter->setPen(m_foreground);painter->drawText(-w / 2, 42, str);
}void MyMeter1::UpdateAngle()
{update();
}// 绘制表针,和中心点
void MyMeter1::drawIndicator(QPainter *painter)
{painter->save();QPolygon pts;pts.setPoints(3, -2, 0, 2, 0, 0, 60);	/* (-2,0)/(2,0)/(0,60) *///第一个参数是 ,坐标的个数。后边的是坐标painter->rotate(m_startAngle);double degRotate = (360.0 - m_startAngle - m_endAngle) / (m_maxValue - m_minValue)*(m_value - m_minValue);//画指针painter->rotate(degRotate);  //顺时针旋转坐标系统QRadialGradient haloGradient(0, 0, 60, 0, 0);  //辐射渐变haloGradient.setColorAt(0, QColor(60, 60, 60));haloGradient.setColorAt(1, QColor(160, 160, 160)); //灰painter->setPen(Qt::white); //定义线条文本颜色  设置线条的颜色painter->setBrush(haloGradient);//刷子定义形状如何填满 填充后的颜色painter->drawConvexPolygon(pts); //这是个重载函数,绘制多边形。painter->restore();//画中心点QColor niceBlue(150, 150, 200);QConicalGradient coneGradient(0, 0, -90.0);  //角度渐变coneGradient.setColorAt(0.0, Qt::darkGray);coneGradient.setColorAt(0.2, niceBlue);coneGradient.setColorAt(0.5, Qt::white);coneGradient.setColorAt(1.0, Qt::darkGray);painter->setPen(Qt::NoPen);  //没有线,填满没有边界painter->setBrush(coneGradient);painter->drawEllipse(-5, -5, 10, 10);
}// 重绘函数
void MyMeter1 ::paintEvent(QPaintEvent *)
{int width=this->width();int height=this->height();QPainter painter(this);//一个类中的this表示一个指向该类自己的指针painter.setRenderHint(QPainter::Antialiasing);  /* 使用反锯齿(如果可用) */painter.translate(width/2, height/2);   /* 坐标变换为窗体中心 */int side = qMin(width, height);painter.scale(side / 200.0, side / 200.0);      /* 比例缩放 */drawCrown(&painter);                                 /* 画表盘边框 */drawScaleNum(&painter);                          /* 画刻度数值值 */drawScale(&painter);                                 /* 画刻度线 */drawTitle(&painter);                                 /* 画单位 */drawNumericValue(&painter);                      /* 画数字显示 */drawIndicator(&painter);                             /* 画表针 */}void MyMeter1::mousePressEvent(QMouseEvent *event){if( (event->button() == Qt::LeftButton) ){mouse_press = true;mousePoint = event->globalPos() - this->pos();//        event->accept();}else if(event->button() == Qt::RightButton){//如果是右键this->close();}
}void MyMeter1::mouseMoveEvent(QMouseEvent *event)
{//    if(event->buttons() == Qt::LeftButton){  //如果这里写这行代码,拖动会有点问题if(mouse_press){move(event->globalPos() - mousePoint);
//        event->accept();}
}void MyMeter1::mouseReleaseEvent(QMouseEvent *event)
{mouse_press = false;
}

meter2.cpp

#include "meter2.h"#include <QPainter>
#include <QBrush>
#include <QLabel>
#include <QTimerEvent>
#include <QLinearGradient>
#include <QFont>#include <QtMath>MyMeter2::MyMeter2(QWidget *parent): QWidget(parent)
{//resize(800, 480);//setWindowTitle("test");m_foreground = Qt::red;//Qt::black;speed = 0;status = 0;m_startAngle = 45;m_endAngle = 45;m_minValue = 0;m_maxValue = 100;m_scaleMajor = 10;//分度m_scaleMinor = 10;m_units = "KM/H";m_title = "My Speed";m_precision = 0;m_value = 0;m_angle = (qreal)270/(m_maxValue-1);//setWindowFlags(Qt::FramelessWindowHint);//无窗体//setAttribute(Qt::WA_TranslucentBackground);//背景透明time_id = this->startTimer(50);
}MyMeter2::~MyMeter2()
{
}void MyMeter2::paintEvent(QPaintEvent *event)
{int width=this->width();int height=this->height();QPainter painter(this);painter.translate(width/2, height/2);int side = qMin(width, height);painter.scale(side / 200.0, side / 200.0);      /* 比例缩放 */drawFrame(&painter);drawScale(&painter);                                 /* 画刻度线 */drawScaleNum(&painter);                          /* 画刻度数值值 */drawUnit(&painter);drawPointer(&painter);drawSpeed(&painter);
}void MyMeter2::drawFrame(QPainter *painter)
{painter->save();// 半径100int radius = 100;painter->setBrush(QBrush(QColor(0, 255, 0, 255), Qt::SolidPattern));painter->drawArc(-radius, -radius, radius<<1, radius<<1, -135*16, -270*16);painter->restore();}// 绘制刻度线
void MyMeter2::drawScale(QPainter *painter)
{painter->save();painter->rotate(m_startAngle);int steps = (m_scaleMajor * m_scaleMinor); //相乘后的值是分的份数double angleStep = (360.0 - m_startAngle - m_endAngle) / steps; //每一个份数的角度// painter->setPen(m_foreground); //m_foreground是颜色的设置// QPen pen = painter->pen(); //第一种方法QPen pen ;pen.setColor(m_foreground); //推荐使用第二种方式for (int i = 0; i <= steps; i++){if (i % m_scaleMinor == 0)//整数刻度显示加粗{pen.setWidth(1); //设置线宽painter->setPen(pen); //使用面向对象的思想,把画笔关联上画家。通过画家画出来painter->drawLine(0, 90, 0, 100); //两个参数应该是两个坐标值}else{pen.setWidth(0);painter->setPen(pen);painter->drawLine(0, 95, 0, 100);}painter->rotate(angleStep);}painter->restore();
}
// 绘制刻度
void MyMeter2::drawScaleNum(QPainter *painter)
{painter->save();painter->setPen(m_foreground);//m_startAngle是起始角度,m_endAngle是结束角度,m_scaleMajor在一个量程中分成的刻度数double startRad = ( 270-m_startAngle) * (3.14 / 180);double deltaRad = (360 - m_startAngle - m_endAngle) * (3.14 / 180) / m_scaleMajor;double sina,cosa;int x, y;QFontMetricsF fm(this->font());double w, h, tmpVal;QString str;for (int i = 0; i <= m_scaleMajor; i++){sina = sin(startRad - i * deltaRad);cosa = cos(startRad - i * deltaRad);tmpVal = 1.0 * i *((m_maxValue - m_minValue) / m_scaleMajor) + m_minValue;// tmpVal = 50;str = QString( "%1" ).arg(tmpVal);  //%1作为占位符   arg()函数比起 sprintf()来是类型安全的w = fm.size(Qt::TextSingleLine,str).width();h = fm.size(Qt::TextSingleLine,str).height();x = 82 * cosa - w / 2;y = -82 * sina + h / 4;painter->drawText(x, y, str); //函数的前两个参数是显示的坐标位置,后一个是显示的内容,是字符类型""}painter->restore();
}void MyMeter2::drawPointer(QPainter *painter)
{int radius = 100;QPoint point[4] = {QPoint(0, 10),QPoint(-10, 0),QPoint(0, -80),QPoint(10, 0),};painter->save();QLinearGradient linear;linear.setStart(-radius, -radius);linear.setFinalStop(radius<<1, radius<<1);linear.setColorAt(0, QColor(0, 255, 255, 0));linear.setColorAt(1, QColor(0, 255, 255, 255));painter->setPen(Qt::NoPen);painter->setBrush(linear);painter->drawPie(-radius, -radius, radius<<1, radius<<1, 225 * 16, -(m_angle * this->speed) * 16);painter->restore();painter->save();painter->setBrush(QBrush(QColor(0, 0, 0, 255), Qt::SolidPattern));painter->rotate(-135 + this->speed * m_angle);painter->drawPolygon(point, 4);painter->restore();
}void MyMeter2::drawSpeed(QPainter *painter)
{painter->save();painter->setPen(QColor("#0"));//  绘制速度QFont font("Times", 10, QFont::Bold);font.setBold(true);font.setPixelSize(46);painter->setFont(font);painter->drawText(-60, 0, 120, 92, Qt::AlignCenter, QString::number(speed));painter->restore();
}void MyMeter2::drawUnit(QPainter *painter)
{QString str = QString("%1").arg(m_units);QFontMetricsF fm(font());double w = fm.size(Qt::TextSingleLine,str).width();painter->setPen(m_foreground);painter->drawText(-w / 2, 82, str);
}void MyMeter2::timerEvent(QTimerEvent *e)
{int timerId = e->timerId();if(this->time_id == timerId) {if(this->status == 0) {this->speed += 1;if(this->speed >= m_maxValue)this->status = 1;}else {this->speed -= 1;if(this->speed <= 0)this->status = 0;}this->update();}
}

main.cpp

#include "mainwindow.h"
#include "meter1.h"
#include "meter2.h"
#include "drawdialog.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MyMeter1 w1;w1.setValue(33.12);w1.show();MyMeter2 w2;w2.show();DrawDialog w3;w3.show();return a.exec();
}

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

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

相关文章

vue视频直接播放rtsp流;vue视频延迟问题解决;webRTC占cpu太大卡死问题解决;解决webRTC播放卡花屏问题:

播放多个视频 <div class"video-box"><div class"video"><iframe style"width:100%;height:100%;" name"ddddd" id"iframes" scrolling"auto" :src"videoLeftUrl"></iframe>&l…

缓存失效方案

一、背景 WRITE &#xff1a; 数据写入Mysql 和 Redis缓存&#xff0c; READ&#xff1a;先从 Redis 缓存中取数据&#xff0c;拿不到再从Mysql中加载&#xff0c;更新到Redis 上图第三阶段&#xff0c;接收Mysql的binlog变更消息&#xff0c;可以参考阿里的 Canal&#xff0…

Ubuntu系统上传文件的多种方法-断网上传-安装包上传-物联网开发维护

一、背景 在全新的Ubuntu系统中&#xff0c;其实是无法执行ifconfig命令的&#xff0c;因为这需要net-tools才能执行。在某些无法连接到外网的情况下&#xff0c;我们常常通过将安装包上传或发送到Ubuntu系统中&#xff0c;解压并安装&#xff0c;以保证相关指令能够执行。 本文…

Python获取微信公众号文章数据

这是一个通过 Python mitmproxy 库 实现获取某个微信公众号下全部文章数据的解决方案。首先需要创建一个 Python 虚拟环境&#xff0c;并进入虚拟环境下&#xff1a; $ python -m venv venv $ venv/Scripts/activate我们需要使用 mitmproxy 库 来建立一个网络代理&#xff0c;…

LeetCode_并查集_DFS_中等_2316.统计无向图中无法互相到达点对数

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你一个整数 n &#xff0c;表示一张 无向图 中有 n 个节点&#xff0c;编号为 0 到 n - 1 。同时给你一个二维整数数组 edges &#xff0c;其中 edges[i] [ai, bi] 表示节点 ai 和 bi 之间有一条无向边。请…

将语义分割的标注mask转为目标检测的bbox

1. 语义分割标签 1.1 labelme工具 语义分割的标签是利用labelme工具进行标注的,标注的样式如下: 1.2 语义分割的标签样式 2. 转换语义分割的标注到目标检测的bbox 实现步骤 (1) 利用标注的json文件生成mask图片(2) 在mask图片中找到目标的bbox矩形框的左上角点和右下角点(…

Redis 之 SessionCallback RedisCallback 使用

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是「奇点」&#xff0c;江湖人称 singularity。刚工作几年&#xff0c;想和大家一同进步&#x1f91d;&#x1f91d; 一位上进心十足的【Java ToB端大厂…

备忘录模式-撤销功能的实现

在idea写代码的过程中&#xff0c;会经常用到一个快捷键——“crtl z”,即撤销功能。“备忘录模式”则为撤销功能提供了一个设计方案。 1 备忘录模式 备忘录模式提供一种状态恢复机制。在不破坏封装的前提下&#xff0c;捕获对象内部状态并在该对象之外保存这个状态。可以在…

Web自动化测试:测试用例断言!

运行测试用例时&#xff0c;需要判断用例是否执行成功&#xff0c;此时需要有一个我们期望的结果来进行验证。这里unittest中&#xff0c;如果一个case执行的过程中报错&#xff0c;或者我们判断结果不符合期望&#xff0c;就会判定此条用例执行失败&#xff0c;判断的条件主要…

【MySQL】数据库——表操作

文章目录 1. 创建表2. 查看表3. 修改表修改表名add ——增加modify——修改drop——删除修改列名称 4. 删除表 1. 创建表 语法&#xff1a; create table 表名字 ( 列名称 列类型 ) charset set 字符集 collate 校验规则 engine 存储引擎 ; charset set字符集 &#xff0c;若…

【C++代码】二叉搜索树的最近公共祖先,二叉搜索树中的插入操作,删除二叉搜索树中的节点--代码随想录

题目&#xff1a;二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&a…

小程序中如何使用自定义组件应用及搭建个人中心布局

一&#xff0c;自定义组件 从小程序基础库版本 1.6.3 开始&#xff0c;小程序支持简洁的组件化编程。所有自定义组件相关特性都需要基础库版本 1.6.3 或更高。 开发者可以将页面内的功能模块抽象成自定义组件&#xff0c;以便在不同的页面中重复使用&#xff1b;也可以将复杂的…

MSQL系列(四) Mysql实战-索引分析Explain命令详解

Mysql实战-索引分析Explain命令详解 前面我们讲解了索引的存储结构&#xff0c;我们知道了BTree的索引结构&#xff0c;也了解了索引最左侧匹配原则&#xff0c;到底最左侧匹配原则在我们的项目中有什么用&#xff1f;或者说有什么影响&#xff1f;今天我们来实战操作一下&…

Java并发面试题:(七)ThreadLocal原理和内存泄漏

ThreadLocal是什么&#xff1f; ThreadLocal是线程本地存储机制&#xff0c;可以将数据缓存在线程内部。ThreadLocal存储的变量在线程内共享的&#xff0c;在线程间又是隔离的。 ThreadLocal实现原理&#xff1f; ThreadLocal的底层是ThreadLocalMap&#xff0c;每个Thread都…

YOLOv5算法改进(16)— 增加小目标检测层 | 四头检测机制(包括代码+添加步骤+网络结构图)

前言:Hello大家好,我是小哥谈。小目标检测层是指在目标检测任务中用于检测小尺寸目标的特定网络层。由于小目标具有较小的尺寸和低分辨率,它们往往更加难以检测和定位。YOLOv5算法的检测速度与精度较为平衡,但是对于小目标的检测效果不佳,根据一些论文,我们可以通过增加检…

Kafka Tool(Kafka 可视化工具)安装及使用教程

Kafka Tool&#xff08;Kafka 可视化工具&#xff09;安装及使用教程 Kafka Tool 工具下载 下载地址 http://www.kafkatool.com/download.html 下载界面 不同版本的Kafka对应不同版本的工具&#xff0c;个人使用的是2.11&#xff0c;所以下载的是最新的2.0.8版本&#xff…

android 13/14高版本SurfaceFlinger出现VSYNC-app/VSYNC-appSf/VSYNC-sf剖析

问题背景&#xff1a; 了解surfaceflinger的vsync同学都可能知道vsync属于一个节拍器&#xff0c;主要用来控制有节奏的渲染&#xff0c;不至于会产生什么画面撕裂等现象。 一般vsync都有会有2部分&#xff1a; app部分vsync&#xff0c;控制各个app可以有节奏的上帧 surfacef…

PyQt学习笔记-获取Hash值的小工具

目录 一、概述1.1 版本信息&#xff1a;1.2 基本信息&#xff1a;1.2.1 软件支持的内容&#xff1a;1.2.2 支持的编码格式 1.3 软件界面图 二、代码实现2.1 View2.2 Controller2.3 Model 三、测试示例 一、概述 本工具居于hashlibPyQtQFileDialog写的小工具&#xff0c;主要是…

【Linux升级之路】8_Linux多线程

目录 一、【Linux初阶】多线程1 | 页表的索引作用&#xff0c;线程基础&#xff08;优缺点、异常、用途&#xff09;&#xff0c;线程VS进程&#xff0c;线程控制&#xff0c;C多线程引入二、【Linux初阶】多线程2 | 分离线程&#xff0c;线程库&#xff0c;线程互斥&#xff0…

【iOS】使用单例封装通过AFNetworking实现的网络请求

这里写目录标题 前言单例封装网络请求1. 首先创建一个继承于NSObject的单例类&#xff0c;笔者这里以Manager对单例类进行命名&#xff0c;然后声明并实现单例类的初始化方法2.实现完单例的创建方法后我们即可通过AFNetworking中的GET方法进行网络请求3.在Controller文件中创建…