当前位置: 首页 > news >正文

libVLC 视频窗口上叠加透明窗口

很多时候,我们需要在界面上画一些三角形、文字等之类的东西,我们之需要重写paintEvent方法,比如像这样

void Widget::paintEvent(QPaintEvent *event)

以下就是重写的代码。 

void Widget::paintEvent(QPaintEvent *event)
{//创建QPainter对象,指明父对象,否则不能看见QPainter painter(this);//先画一条线QPen pen;//设置线宽pen.setWidth(2);//设置颜色pen.setColor(Qt::red);//设置线的样式 实线、虚线pen.setStyle(Qt::DashDotLine);//设置线端点样式pen.setCapStyle(Qt::RoundCap);//设置画笔painter.setPen(pen);//画线painter.drawLine(10,10,100,100);//设置画刷QBrush brush;//画刷设置颜色brush.setColor(Qt::yellow);//设置填充样式brush.setStyle(Qt::SolidPattern);//设置画刷painter.setBrush(brush);//画四边形painter.drawRect(QRect(300,300,50,50));//画多边形,三角形QPoint points[] = {QPoint(200,200),QPoint(200,260),QPoint(260,260),};painter.drawPolygon(points,3);//设置字体QFont font;//字体大小font.setPointSize(30);//粗体font.setBold(true);//设置字体painter.setFont(font);//画字painter.drawText(400,400,QString("Qt"));
}

运行如下图所示:

更多QPainter相关的东西,请看:

Qt QPainter绘图_qt painter-CSDN博客 

但是现在我们需要在播放视频的界面上绘制窗体,像下面这样。

这里我叠加了一个Widget在上面,widget上放了两个控件,一个label和一个comboBox。

ui原型如下所示:

首先我们需要定义一个叠加窗体类TopWidget,

这个类很简单,设置了窗体无边框和透明。

	//窗口无边框setWindowFlags(Qt::FramelessWindowHint | Qt::Window);// 窗口透明this->setAttribute(Qt::WA_TranslucentBackground);

然后重写绘图事件。 

#pragma once#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include "ui_TopWidget.h"class TopWidget : public QWidget
{Q_OBJECTpublic:TopWidget(QWidget *parent = nullptr);~TopWidget();protected:void paintEvent(QPaintEvent *pEvent);private:Ui::TopWidgetClass ui;
};#include "TopWidget.h"TopWidget::TopWidget(QWidget *parent): QWidget(parent)
{ui.setupUi(this);//窗口无边框setWindowFlags(Qt::FramelessWindowHint | Qt::Window);// 窗口透明this->setAttribute(Qt::WA_TranslucentBackground);
}TopWidget::~TopWidget()
{}void TopWidget::paintEvent(QPaintEvent *pEvent)
{QStyleOption opt;opt.initFrom(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);//绘制样式
}

 在主界面中,创建叠加窗体对象:

    TopWidget *m_widget = nullptr;	m_widget = new TopWidget(this);m_widget->setStyleSheet(QString("background-color: rgba(255, 0, 0, 0%);"));m_widget->show();

重写绘图和窗体移动事件:我们需要在主窗体移动的时候,叠加窗体跟随着主窗体移动。

void showWidget::paintEvent(QPaintEvent *event)
{QStyleOption opt;opt.initFrom(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);//绘制样式QPoint pos_form = ui.widgetShow->mapToGlobal(ui.widgetShow->pos());m_widget->move(pos_form);m_widget->setGeometry(pos_form.x(), pos_form.y(), ui.widgetShow->width(), ui.widgetShow->height());
}void showWidget::moveEvent(QMoveEvent *event)
{QPoint pos_form = ui.widgetShow->mapToGlobal(ui.widgetShow->pos());m_widget->move(pos_form);m_widget->setGeometry(pos_form.x(), pos_form.y(), ui.widgetShow->width(), ui.widgetShow->height());
}

完整源码:

#pragma once
#define LIBVLC_USE_PTHREAD_CANCEL 1
#include <QtWidgets/QWidget>
#include "ui_showWidget.h"
#include <QMenu>
#include <QActionGroup>
#include <vlc/vlc.h>#include <QDebug>
#include <QFileDialog>
#include <QThread>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QPainter>
#include "TopWidget.h"enum Rate
{Rate2X,Rate1_5X,Rate1_25X,Rate1_0X,Rate0_75X,Rate0_5X
};class showWidget : public QWidget
{Q_OBJECTpublic:showWidget(QWidget *parent = nullptr);~showWidget();protected:virtual void mouseDoubleClickEvent(QMouseEvent *event);virtual void keyPressEvent(QKeyEvent *event);virtual bool eventFilter(QObject *watched, QEvent *event);virtual void paintEvent(QPaintEvent *event);virtual void moveEvent(QMoveEvent *event);private slots:void slotOpenFile();void slotPlay();void slotPause();void slotStop();void slotValueChanged(int value);void slotCurrentIndexChanged(int index);void slotSnap();private://事件处理回调static void vlcEvents(const libvlc_event_t *ev, void *param);private:Ui::showWidgetClass ui;private:libvlc_instance_t *vlc_base = nullptr;libvlc_media_t *vlc_media = nullptr;libvlc_media_player_t *vlc_mediaPlayer = nullptr;QList<float> m_lstRate;TopWidget *m_widget = nullptr;
};#include "showWidget.h"
#include <QTimer>
#include <QTime>
#include <QFileDialog>#pragma execution_character_set("utf-8")showWidget::showWidget(QWidget *parent): QWidget(parent)
{ui.setupUi(this);m_widget = new TopWidget(this);m_widget->setStyleSheet(QString("background-color: rgba(255, 0, 0, 0%);"));m_widget->show();this->setWindowTitle("视频播放器");ui.cbxRate->setCurrentIndex(Rate1_0X);m_lstRate << 2.0 << 1.5 << 1.25 << 1.0 << 0.75 << 0.5;vlc_base = libvlc_new(0, NULL);ui.btnOpen->setFocusPolicy(Qt::NoFocus);ui.btnPlay->setFocusPolicy(Qt::NoFocus);ui.btnPause->setFocusPolicy(Qt::NoFocus);ui.btnStop->setFocusPolicy(Qt::NoFocus);ui.hSliderVolumn->setFocusPolicy(Qt::NoFocus);ui.cbxRate->setFocusPolicy(Qt::NoFocus);ui.horizontalSlider->installEventFilter(this);connect(ui.btnOpen, &QPushButton::clicked, this, &showWidget::slotOpenFile);connect(ui.btnPlay, &QPushButton::clicked, this, &showWidget::slotPlay);connect(ui.btnPause, &QPushButton::clicked, this, &showWidget::slotPause);connect(ui.btnStop, &QPushButton::clicked, this, &showWidget::slotStop);connect(ui.btnSnap, &QPushButton::clicked, this, &showWidget::slotSnap);connect(ui.hSliderVolumn, &QSlider::valueChanged, this, &showWidget::slotValueChanged);connect(ui.cbxRate,SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentIndexChanged(int)));
}showWidget::~showWidget()
{libvlc_release(vlc_base); //减少libvlc实例的引用计数,并销毁
}void showWidget::mouseDoubleClickEvent(QMouseEvent *event)
{if (this->isFullScreen()){this->showNormal();}else{this->showFullScreen();}
}void showWidget::keyPressEvent(QKeyEvent *event)
{if (!vlc_mediaPlayer)return;int value = ui.hSliderVolumn->value();if (event->key() == Qt::Key_W)	//添加音量{qDebug() << "up";slotValueChanged(value+10);}else if (event->key() == Qt::Key_S)	//减小音量{slotValueChanged(value - 10);}else if (event->key() == Qt::Key_Space){if (vlc_mediaPlayer && libvlc_media_player_get_state(vlc_mediaPlayer) == libvlc_Playing){libvlc_media_player_pause(vlc_mediaPlayer);}else if (vlc_mediaPlayer && libvlc_media_player_get_state(vlc_mediaPlayer) == libvlc_Paused){libvlc_media_player_play(vlc_mediaPlayer);}}
}bool showWidget::eventFilter(QObject *watched, QEvent *event)
{if (watched == ui.horizontalSlider) {if (event->type() == QEvent::MouseButtonPress) {if (!vlc_mediaPlayer)return false;QMouseEvent *mouse = static_cast<QMouseEvent*>(event);libvlc_time_t totalLen = libvlc_media_player_get_length(vlc_mediaPlayer);QPoint pos = mouse->pos();libvlc_time_t time = 0;time = (double)pos.x() / ui.horizontalSlider->width() * totalLen;libvlc_media_player_set_time(vlc_mediaPlayer, time);return true;}else {return false;}}else {// pass the event on to the parent classreturn QWidget::eventFilter(watched, event);}
}void showWidget::paintEvent(QPaintEvent *event)
{QStyleOption opt;opt.initFrom(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);//绘制样式QPoint pos_form = ui.widgetShow->mapToGlobal(ui.widgetShow->pos());m_widget->move(pos_form);m_widget->setGeometry(pos_form.x(), pos_form.y(), ui.widgetShow->width(), ui.widgetShow->height());
}void showWidget::moveEvent(QMoveEvent *event)
{QPoint pos_form = ui.widgetShow->mapToGlobal(ui.widgetShow->pos());m_widget->move(pos_form);m_widget->setGeometry(pos_form.x(), pos_form.y(), ui.widgetShow->width(), ui.widgetShow->height());
}void showWidget::slotOpenFile()
{/*选择文件*/QString filename = QFileDialog::getOpenFileName(this, "选择打开的文件", "D:/", tr("*.*"));std::replace(filename.begin(), filename.end(), QChar('/'), QChar('\\'));vlc_media = libvlc_media_new_path(vlc_base, filename.toUtf8().data());if (!vlc_media) {return;}// 创建libvlc实例和媒体播放器vlc_mediaPlayer = libvlc_media_player_new_from_media(vlc_media);if (!vlc_mediaPlayer) {return;}// 等待元数据加载完成libvlc_media_parse(vlc_media);libvlc_video_set_mouse_input(vlc_mediaPlayer, 0);libvlc_video_set_key_input(vlc_mediaPlayer, 0);// 获取各种元数据const char *title = libvlc_media_get_meta(vlc_media, libvlc_meta_Title);const char *artist = libvlc_media_get_meta(vlc_media, libvlc_meta_Artist);const char *album = libvlc_media_get_meta(vlc_media, libvlc_meta_Album);const char *url = libvlc_media_get_meta(vlc_media, libvlc_meta_URL);const char *date = libvlc_media_get_meta(vlc_media, libvlc_meta_Date);const char *lang = libvlc_media_get_meta(vlc_media, libvlc_meta_Language);int duration = libvlc_media_get_duration(vlc_media);  // 获取时长(单位:毫秒)qDebug("Title: %s", title ? title : "N/A");qDebug("Artist: %s", artist ? artist : "N/A");qDebug("Album: %s", album ? album : "N/A");qDebug("Duration: %d ms", duration);qDebug("url: %s", url ? url : "N/A");qDebug("date: %s", date ? date : "N/A");qDebug("lang: %s", lang ? lang : "N/A");libvlc_media_track_t **tracks;int track_count = libvlc_media_tracks_get(vlc_media,&tracks);for (unsigned i = 0; i < track_count; i++) {libvlc_media_track_t* track = tracks[i];// 显示轨道信息printf("Track #%u: %s\n", i, track->psz_description);// 这里可以获取到每一个轨道的信息,比如轨道类型 track->i_type// 可能是 libvlc_track_video, libvlc_track_audio 或者 libvlc_track_text (字幕)if (track->i_type == libvlc_track_video) {// 处理视频轨道信息qDebug("width = %d",track->video->i_width);qDebug("height = %d", track->video->i_height);qDebug("rate_num = %d", track->video->i_frame_rate_num);qDebug("rate_den = %d", track->video->i_frame_rate_den);}else if (track->i_type == libvlc_track_audio) {// 处理音频轨道信息qDebug("channels = %d", track->audio->i_channels);qDebug("rate = %d", track->audio->i_rate);}else if (track->i_type == libvlc_track_text) {// 处理字幕轨道信息qDebug("psz_encoding = %s", track->subtitle->psz_encoding);}}//获取事件管理器libvlc_event_manager_t *em = libvlc_media_player_event_manager(vlc_mediaPlayer);// 注册事件监听器libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, vlcEvents, this);libvlc_event_attach(em, libvlc_MediaPlayerEndReached, vlcEvents, this);libvlc_event_attach(em, libvlc_MediaPlayerStopped, vlcEvents, this);libvlc_event_attach(em, libvlc_MediaPlayerPlaying, vlcEvents, this);libvlc_event_attach(em, libvlc_MediaPlayerPaused, vlcEvents, this);libvlc_media_player_set_hwnd(vlc_mediaPlayer, (void *)ui.widgetShow->winId());QTimer::singleShot(1000, this, &showWidget::slotPlay);}void showWidget::slotPlay()
{if (vlc_mediaPlayer)libvlc_media_player_play(vlc_mediaPlayer);
}void showWidget::slotPause()
{if (vlc_mediaPlayer)libvlc_media_player_pause(vlc_mediaPlayer);
}void showWidget::slotStop()
{if (vlc_mediaPlayer)libvlc_media_player_stop(vlc_mediaPlayer);
}void showWidget::slotValueChanged(int value)
{if (vlc_mediaPlayer)libvlc_audio_set_volume(vlc_mediaPlayer, value);
}void showWidget::slotCurrentIndexChanged(int index)
{if (vlc_mediaPlayer)libvlc_media_player_set_rate(vlc_mediaPlayer, m_lstRate[index]);
}void showWidget::slotSnap()
{if (vlc_mediaPlayer){QString path = "./snap.png";libvlc_video_take_snapshot(vlc_mediaPlayer, 0, path.toUtf8().data(), 0, 0);}
}//事件回调
void showWidget::vlcEvents(const libvlc_event_t *ev, void *param)
{showWidget *w = (showWidget*)param;//处理不同的事件switch (ev->type) {case libvlc_MediaPlayerTimeChanged:{//qDebug() << "VLC媒体播放器时间已更改";qint64 len = libvlc_media_player_get_time(w->vlc_mediaPlayer);libvlc_time_t lenSec = len / 1000;libvlc_time_t totalLen = libvlc_media_player_get_length(w->vlc_mediaPlayer);libvlc_time_t totalLenSec = totalLen / 1000;int thh, tmm, tss;thh = lenSec / 3600;tmm = (lenSec % 3600) / 60;tss = (lenSec % 60);QTime time(thh, tmm, tss);w->ui.lbCurTime->setText(time.toString("hh:mm:ss"));thh = totalLenSec / 3600;tmm = (totalLenSec % 3600) / 60;tss = (totalLenSec % 60);QTime TotalTime(thh, tmm, tss);w->ui.lbTotalTime->setText(TotalTime.toString("hh:mm:ss"));double pos = (double)lenSec / totalLenSec * 100;w->ui.horizontalSlider->setValue(pos);}break;case libvlc_MediaPlayerEndReached:qDebug() << "VLC播放完毕.";break;case libvlc_MediaPlayerStopped:qDebug() << "VLC停止播放";break;case libvlc_MediaPlayerPlaying:qDebug() << "VLC开始播放";break;case libvlc_MediaPlayerPaused:qDebug() << "VLC暂停播放";break;}
}

更多参考:

Qt+FFmpeg+opengl从零制作视频播放器-1.项目介绍_qt opengl视频播放器-CSDN博客

libVLC 提取视频帧使用OpenGL渲染-CSDN博客

QT UDP通信(单播、广播、组播)-CSDN博客

QCharts -1.概述-CSDN博客

相关文章:

libVLC 视频窗口上叠加透明窗口

很多时候&#xff0c;我们需要在界面上画一些三角形、文字等之类的东西&#xff0c;我们之需要重写paintEvent方法&#xff0c;比如像这样 void Widget::paintEvent(QPaintEvent *event) 以下就是重写的代码。 void Widget::paintEvent(QPaintEvent *event) {//创建QPainte…...

MySQL基础入门上篇

MySQL基础 介绍 mysql -uroot -p -h127.0.0.1 -P3306项目设计 具备数据库一定的设计能力和操作数据的能力。 数据库设计DDL 定义 操作 显示所有数据库 show databases;创建数据库 create database db02;数据库名唯一&#xff0c;不能重复。 查询是否创建成功 加入一些…...

Docker搭建FFmpeg

FFmpeg 是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的完整解决方案。FFmpeg 包含了领先的音视频编解码库libavcodec&#xff0c;可以用于各种视频格式的转换。 应用场景包括&#xff1a; 视频转换&#xff1a;把视频从一种格式转换成另一种格式。视…...

Hudi-ubuntu环境搭建

hudi-ubuntu环境搭建 运行 1.编译Hudi #1.把maven安装包上传到服务器 # 官网下载安装包 https://archive.apache.org/dist/maven/maven-3/ scp -r D:\Users\zh\Desktop\Hudi\compressedPackage\apache-maven-3.6.3-bin.tar.gz zhangheng10.8.4.212:/home/zhangheng/hudi/com…...

Hive进阶Day05

一、HDFS分布式文件存储系统 1-1 HDFS的存储机制 按块&#xff08;block&#xff09;存储 hdfs在对文件数据进行存储时&#xff0c;默认是按照128M(包含)大小进行文件数据拆分&#xff0c;将不同拆分的块数据存储在不同datanode服务器上 拆分后的块数据会被分别存储在不同的服…...

ssh爆破服务器的ip-疑似肉鸡

最近发现自己的ssh一直有一些人企图使用ssh暴力破解的方式进行密码破解.就查看了一下,真是网络安全太可怕了. 大家自己的服务器密码还是要设置好,管好,做好最基本的安全措施,不然最后只能沦为肉鸡. ssh登陆日志可以在/var/log下看到,ubuntu的话为auth.log,centos为secure文件 查…...

4.JVM八股

JVM空间划分 线程共享和线程私有 1.7&#xff1a; 线程共享&#xff1a; 堆、方法区 线程私有&#xff1a; 虚拟机栈、本地方法栈、程序计数器 本地内存 1.8&#xff1a; 线程共享&#xff1a; 堆 线程私有&#xff1a; 老三样 本地内存&#xff0c;元空间 程序计数器 …...

内网渗透系列-mimikatz的使用以及后门植入

内网渗透系列-mimikatz的使用以及后门植入 文章目录 内网渗透系列-mimikatz的使用以及后门植入前言mimikatz的使用后门植入 msf永久后门植入 &#xff08;1&#xff09;Meterpreter后门&#xff1a;Metsvc&#xff08;2&#xff09;Meterpreter后门&#xff1a;Persistence NC后…...

5G网络开通与调测ipv4

要求如下&#xff1a; 1. 勘站规划 1. 【重】首先观察NR频点&#xff0c;完成设备选型 2645--选择N41 3455--选择N78 4725--选择N79 设备选型如下&#xff1a;观察AAU的通道数&#xff0c;最大发射功率&#xff1b;选择N41的选型频段也要选41 2. …...

Spark开窗函数之ROW

Spark 1.5.x版本以后,在Spark SQL和DataFrame中引入了开窗函数,其中比较常用的开窗函数就是row_number 该函数的作用是根据表中字段进行分组,然后根据表中的字段排序;其实就是根据其排序顺序,给组中的每条记录添 加一个序号;且每组的序号都是从1开始,可利用它的这个特性进行分组…...

双向链表的实现(详解)

目录 前言初始化双向链表的结构为双向链表的节点开辟空间头插尾插打印链表尾删头删查找指定位置之后的插入删除pos节点销毁双向链表 前言 链表的分类&#xff1a; 带头 不带头 单向 双向 循环 不循环 一共有 (2 * 2 * 2) 种链表 带头指的是&#xff1a;带有哨兵位节点 哨兵位&a…...

SpringBoot项目中如何使用校验工具

用到hutool提供的校验方法与java提供的校验方法 1. 声明数据 String str "123" String regex "^123456$" Boolean is1_6 mismatch(str, regex);2. 定义校验方法 // 校验是否不符合正则格式 private static boolean mismatch(String str, String rege…...

AI预测小分子与蛋白的相关特征: MegaMolBART, MoFlow,ESM-1, ESM-2

1、小分子:MegaMolBART, MoFlow 1)MegaMolBART https://github.com/NVIDIA/MegaMolBART 基于 SMILES 的小分子药物发现与化学信息学深度学习模型。 2)MoFlow https://github.com/calvin-zcx/moflow 用flow流方式分子生成 2、蛋白质:ESM-1, ESM-2 https://github.com/fa…...

基于深度学习的花卉检测系统(含PyQt界面)

基于深度学习的花卉检测系统&#xff08;含PyQt界面&#xff09; 前言一、数据集1.1 数据集介绍1.2 数据预处理 二、模型搭建三、训练与测试3.1 模型训练3.2 模型测试 四、PyQt界面实现参考资料 前言 本项目是基于swin_transformer深度学习网络模型的花卉检测系统&#xff0c;…...

深度学习图像处理基础工具——opencv 实战信用卡数字识别

任务 信用卡数字识别 穿插之前学的知识点 形态学操作 模板匹配 等 总体流程与方法 1.有一个模板 2 用轮廓检测把模板中数字拿出来 外接矩形&#xff08;模板和输入图像的大小要一致 &#xff09;3 一系列预处理操作 问题的解决思路 1.分析准备&#xff1a;准备模板&#…...

【HBase】HBase高性能架构:如何保证大规模数据的高可用性

HBase高性能原理 HBase 能够提供高性能的数据处理能力&#xff0c;主要得益于其设计和架构的几个关键方面。这些设计特点使得 HBase 特别适合于大规模、分布式的环境中进行高效的数据读写操作。以下是 HBase 高性能的主要原因&#xff1a; 1. 基于列的存储 HBase 是一个列式…...

JAVA基础两个项目案例代码

1.JAVA使用ArrayList上架菜品案例 视频参考链接 创建一个Food.java类 package org.example;// 菜品类 public class Food {private String name; // 菜品名private double price; // 价格private String desc; // 菜品描述public Food() {}public Food(String name, Double …...

asp.net core 网页接入微信扫码登录

创建微信开放平台账号&#xff0c;然后创建网页应用 获取appid和appsecret 前端使用的vue&#xff0c;安装插件vue-wxlogin 调用代码 <wxlogin :appid"appId" :scope"scope" :redirect_uri"redirect_uri"></wxlogin> <scri…...

【板栗糖GIS】如何给微软拼音输入法加上小鹤双拼

【板栗糖GIS】如何给微软拼音输入法加上小鹤双拼 用过在注册表里新建的方法&#xff0c;结果弄完没有出现小鹤双拼方案&#xff0c;想到了自己写reg表 目录 1. 新建一个txt文件 2. 把.txt的后缀名改成.reg&#xff0c;双击运行 3. 在设置中找到微软输入法-常规 1. 新建一个…...

如何解决微信小程序无法使用css3过度属性transition

由于微信小程序不支持CSS3过度属性transition,所以我们需要利用微信小程序api进行画面过度的展示 首先是官方示例: wxml: <view animation="{{animationData}}" style="background:red;height:100rpx;width:100rpx"></view> js: Page(…...

【软件设计师知识点】九、网络与信息安全基础知识

文章目录 计算机网络的概念网络分类网络拓扑结构网络体系结构ISO/OSI 7层参考模型TCP/IP 4层模型TCP/IP 协议族应用层协议传输层协议网络层协议IP 地址IPV4 数据报IP 地址分类子网划分子网掩码IPv6地址...

广东省道路货物运输资格证照片回执可手机线上办理

广东省道路运输资格证是从事道路运输业务、危险品道路运输人员的必要证件&#xff0c;而在办理该证件的过程中&#xff0c;驾驶员照片回执是一项必不可少的材料。随着科技的发展和移动互联网的普及&#xff0c;现在办理驾驶员照片回执已经不再需要亲自前往照相馆&#xff0c;而…...

【微信小程序——案例——本地生活(列表页面)】

案例——本地生活&#xff08;列表页面&#xff09; 九宫格中实现导航跳转——以汽车服务为案例&#xff08;之后可以全部实现页面跳转——现在先实现一个&#xff09; 在app.json中添加新页面 修改之前的九宫格view改为navitage 效果图&#xff1a; 动态设置标题内容—…...

【设计模式】SOLID设计原则

1、什么是SOLID设计原则 SOLID 是面向对象设计中的五个基本设计原则的首字母缩写&#xff0c;它们是&#xff1a; 单一职责原则&#xff08;Single Responsibility Principle&#xff0c;SRP&#xff09;&#xff1a; 类应该只有一个单一的职责&#xff0c;即一个类应该有且只…...

基于java+springboot+vue实现的智能停车计费系统(文末源码+Lw+ppt)23-30

摘 要 随着人们生活水平的高速发展&#xff0c;智能停车计费信息管理方面在近年来呈直线上升&#xff0c;人们也了解到智能停车计费的实用性&#xff0c;因此智能停车计费的管理也逐年递增&#xff0c;智能停车计费信息的增加加大了在管理上的工作难度。为了能更好的维护智能…...

IntelliJ IDEA 2022.3.2 解决decompiled.class file bytecode version:52.0(java 8)

1 背景 使用idea 打开一个Kotlin语言编写的demo项目&#xff0c;该项目使用gradle构建。其gradle文件如下&#xff1a; plugins {id javaid org.jetbrains.kotlin.jvm version 1.8.20 } group me.administrator version 1.0-SNAPSHOTrepositories {mavenCentral()jcenter()…...

C++11 设计模式1. 模板方法(Template Method)模式学习。UML图

一 什么是 "模板方法&#xff08;Template Method&#xff09;模式" 在固定步骤确定的情况下&#xff0c;通过多态机制在多个子类中对每个步骤的细节进行差异化实现&#xff0c;这就是模板方法模式能够达到的效果。 模板方法模式属于&#xff1a;行为型模式。 二 &…...

HarmonyOS实战开发-自定义分享

介绍 自定义分享主要是发送方将文本&#xff0c;链接&#xff0c;图片三种类型分享给三方应用,同时能够在三方应用中展示。本示例使用数据请求 实现网络资源的获取&#xff0c;使用屏幕截屏 实现屏幕的截取&#xff0c;使用文件管理 实现对文件&#xff0c;文件目录的管理&…...

Spring源码刨析之配置文件的解析和bean的创建以及生命周期

public void test1(){XmlBeanFactory xmlBeanFactory new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));user u xmlBeanFactory.getBean("user",org.xhpcd.user.class);// System.out.println(u.getStu());}先介绍一个类XmlBeanFac…...

如何使用 Grafana 监控文件系统状态

当 JuiceFS 文件系统部署完成并投入生产环境&#xff0c;接下来就需要着手解决一个非常重要的问题 —— 如何实时监控它的运行状态&#xff1f;毕竟&#xff0c;它可能正在为关键的业务应用或容器工作负载提供持久化存储支持&#xff0c;任何小小的故障或性能下降都可能造成不利…...

建设网站政策风险/广告营销包括哪些方面

数据库驱动 1.数据库驱动的概念 数据库厂商提供的用来操作数据库的jar包&#xff0c;就叫做数据库的驱动。 JDBC 1.1.JDBC的概念: (掌握) 1.1.1.数据库驱动: 数据库厂商提供的用来操作数据库的jar包 1.1.2.JDBC: 由于不同的数据库厂商提供的数据库驱动各不相同,导…...

wordpress+主题页脚/网络营销策划书格式

文章目录1、文件和目录的默认权限2、umask 默认权限&#xff08;1&#xff09;查看系统的umask权限&#xff08;2&#xff09;用八进制数值显示umask权限&#xff08;3&#xff09;umask权限的计算方法&#xff08;4&#xff09;注意&#xff1a;umask 默认权限的计算绝不是数字…...

vm虚拟机搭建wordpress/爱站网影院

数据结构与算法学习笔记(3):线性表Ⅰ 本系列笔记为跟着B站上王卓老师的教程学习所记录的笔记 文章目录数据结构与算法学习笔记(3):线性表Ⅰ一.线性表的定义和特点1.定义2.特点线性表的逻辑特征二.典型案例1.一元多项式运算2.稀疏多项式3.图书信息管理系统逻辑结构存储结构可以用…...

动态网站与静态网站的区别/农产品推广方案

Inventory是什么 Inventory 文件主要用来填写被管理主机以及主机组信息&#xff0c;&#xff08;逻辑上定义&#xff09;&#xff0c;默认Inventory文件为/etc/ansible/hosts。 当然也可以自定义一个文件&#xff0c;当执行 ansible 命令时使用-i选项指定 Inventory 文件位置。…...

wdcp 快速迁移网站/营销平台建设

在用五笔加加Plus打字时&#xff0c;打了一会儿切换个输入法&#xff0c;再换回来时就只能输入字母了。转载于:https://www.cnblogs.com/wuchang/archive/2004/08/20/35092.html...

zhihe网站建设 淘宝/近期国际新闻

1. 模板的概念。 我们已经学过重载(Overloading)&#xff0c;对重载函数而言,C的检查机制能通过函数参数的不同及所属类的不同。正确的调用重载函数。例如&#xff0c;为求两个数的最大值&#xff0c;我们定义MAX()函数需要对不同的数据类型分别定义不同重载(Overload)版本。 /…...