libVLC 视频裁剪

使用 libVLC 进行视频裁剪并不是直接支持的功能,因为 libVLC 主要是一个媒体播放库。然而,你可以通过调整播放窗口的大小和设置视频输出的区域来实现一种“视觉上的裁剪”。这意味着视频本身并没有被修改,但可以控制显示给用户的视频区域。

如果你的目标是在播放时只显示视频的一部分,你可以通过设置视频输出的裁剪区域来实现。以下是如何使用 libVLC 设置视频裁剪区域的基本步骤:

1. 初始化 libVLC 和媒体播放器

首先,你需要初始化 libVLC 实例和媒体播放器对象。

#include <vlc/vlc.h>int main(int argc, char* argv[])
{libvlc_instance_t* inst;libvlc_media_player_t* mp;libvlc_media_t* m;// 加载 libVLC 引擎inst = libvlc_new(0, NULL);// 创建一个新的 itemm = libvlc_media_new_location(inst, "your_video_path_here");mp = libvlc_media_player_new_from_media(m);// 不再需要媒体对象libvlc_media_release(m);
}

2. 设置视频裁剪区域

你可以通过设置 libvlc_video_set_crop_geometry 来指定裁剪区域。这个函数允许你指定一个裁剪区域,格式为 “NxN”(例如,“16:9”、“4:3” 等)或者像素值(例如 “640x480”)。

// 设置裁剪区域
libvlc_video_set_crop_geometry(mp, "16:9");

3. 播放视频

最后,播放视频。

// 播放媒体播放器
libvlc_media_player_play(mp);// 保持程序运行,直到视频播放完成
while (libvlc_media_player_is_playing(mp)) {// 可以在这里加入延时
}// 清理 libVLC
libvlc_media_player_stop(mp);
libvlc_media_player_release(mp);
libvlc_release(inst);return 0;

以下是VLC播放器中使用的视频裁剪,我们仿照这个做一个界面。 

以下是做出来的效果:

首先做一个菜单:

//设置裁剪菜单m_cropMenu = new QMenu(this);m_cropAction->setMenu(m_cropMenu);m__cropDefault = m_cropMenu->addAction(QIcon(":/image/images/point.png"), "默认");m__crop16_10 = m_cropMenu->addAction("16:10");m__crop16_9 = m_cropMenu->addAction("16:9");m__crop4_3 = m_cropMenu->addAction("4:3");m__crop1_85_1 = m_cropMenu->addAction("1.85:1");m__crop2_21_1 = m_cropMenu->addAction("2.21:1");m__crop2_35_1 = m_cropMenu->addAction("2.35:1");m__crop2_39_1 = m_cropMenu->addAction("2.39:1");m__crop5_3 = m_cropMenu->addAction("5:3");m__crop5_4 = m_cropMenu->addAction("5:4");m__crop1_1 = m_cropMenu->addAction("1:1");m_preCrop = m__cropDefault;m_cropGroup = new QActionGroup(this);m_cropGroup->addAction(m__cropDefault);m_cropGroup->addAction(m__crop16_10);m_cropGroup->addAction(m__crop16_9);m_cropGroup->addAction(m__crop4_3);m_cropGroup->addAction(m__crop1_85_1);m_cropGroup->addAction(m__crop2_21_1);m_cropGroup->addAction(m__crop2_35_1);m_cropGroup->addAction(m__crop2_39_1);m_cropGroup->addAction(m__crop5_3);m_cropGroup->addAction(m__crop5_4);m_cropGroup->addAction(m__crop1_1);connect(m_cropGroup, &QActionGroup::triggered, this, &showWidget::slotCropActionTriggered);

接受槽函数的响应事件:

void showWidget::slotCropActionTriggered(QAction *action)
{if (!vlc_mediaPlayer)return;if (action == m__cropDefault)libvlc_video_set_crop_geometry(vlc_mediaPlayer, m_defalutCrop);else if (action == m__crop16_10)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "16:10");else if (action == m__crop16_9)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "16:9");else if (action == m__crop4_3)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "4:3");else if (action == m__crop1_85_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "185:100");else if (action == m__crop2_21_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "221:100");else if (action == m__crop2_35_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "235:100");else if (action == m__crop2_39_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "239:100");else if (action == m__crop5_3)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "5:3");else if (action == m__crop5_4)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "5:4");else if (action == m__crop1_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "1:1");action->setIcon(QIcon(":/image/images/point.png"));m_preCrop->setIcon(QIcon());m_preCrop = action;
}

设置鼠标右键弹出菜单:重写鼠标点击事件,弹出菜单。

首先设置libvlc忽略鼠标事件libvlc_video_set_mouse_input(vlc_mediaPlayer, 0);

再重写鼠标事件:

void showWidget::mousePressEvent(QMouseEvent *event)
{switch (event->button()){case Qt::RightButton://this->setWindowState(Qt::WindowMinimized);m_menu->exec(event->globalPos());break;default:QWidget::mousePressEvent(event);}
}

完整代码:

头文件。

#pragma once#include <QtWidgets/QWidget>
#include "ui_showWidget.h"
#include <QMenu>
#include <QActionGroup>
#include <vlc/vlc.h>
#include <QDebug>
#include <QFileDialog>
#include <QThread>
#include <QMouseEvent>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 mousePressEvent(QMouseEvent *event);private slots:void slotOpenFile();void slotPlay();void slotPause();void slotStop();void slotValueChanged(int value);void slotCurrentIndexChanged(int index);void slotActionTriggered(QAction *action);void slotCropActionTriggered(QAction *action);private://事件处理回调static void vlcEvents(const libvlc_event_t *ev, void *param);//初始化menuvoid initMenu();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;QMenu *m_menu = nullptr;QAction *m_video = nullptr;QAction *m_scaleAction = nullptr;	//缩放QAction *m_aspectRatioAction = nullptr;	//宽高比QAction *m_cropAction = nullptr;	//裁剪QMenu *m_videoMenu = nullptr;//宽高比QMenu *m_aspectRatioMenu = nullptr;QAction *m_default = nullptr;QAction *m_16_9 = nullptr;QAction *m_4_3 = nullptr;QAction *m_1_1 = nullptr;QAction *m_16_10 = nullptr;QAction *m_2_21_1 = nullptr;QAction *m_2_35_1= nullptr;QAction *m_2_38_1 = nullptr;QAction *m_5_4 = nullptr;QActionGroup *m_group = nullptr;QAction *m_preAspectRatio = nullptr;//宽高比//裁剪QMenu *m_cropMenu = nullptr;QAction *m__cropDefault = nullptr;QAction *m__crop16_10 = nullptr;QAction *m__crop16_9 = nullptr;QAction *m__crop4_3 = nullptr;QAction *m__crop1_85_1 = nullptr;QAction *m__crop2_21_1 = nullptr;QAction *m__crop2_35_1 = nullptr;QAction *m__crop2_39_1 = nullptr;QAction *m__crop5_3 = nullptr;QAction *m__crop5_4 = nullptr;QAction *m__crop1_1 = nullptr;QActionGroup *m_cropGroup = nullptr;QAction *m_preCrop= nullptr;//裁剪char *m_defalutRate = nullptr;char *m_defalutCrop = nullptr;
};

cpp文件。 

#include "showWidget.h"
#include <QTimer>
#include <QTime>#pragma execution_character_set("utf-8")showWidget::showWidget(QWidget *parent): QWidget(parent)
{ui.setupUi(this);this->setWindowTitle("视频播放器");ui.cbxRate->setCurrentIndex(Rate1_0X);m_lstRate << 2.0 << 1.5 << 1.25 << 1.0 << 0.75 << 0.5;initMenu();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.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::mousePressEvent(QMouseEvent *event)
{switch (event->button()){case Qt::RightButton://this->setWindowState(Qt::WindowMinimized);m_menu->exec(event->globalPos());break;default:QWidget::mousePressEvent(event);}
}void showWidget::slotOpenFile()
{/*选择文件*/QString filename = QFileDialog::getOpenFileName(this, "选择打开的文件", "D:/", tr("*.*"));std::replace(filename.begin(), filename.end(), QChar('/'), QChar('\\'));vlc_base = libvlc_new(0, NULL);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);m_defalutRate = libvlc_video_get_aspect_ratio(vlc_mediaPlayer);m_defalutCrop = libvlc_video_get_crop_geometry(vlc_mediaPlayer);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) {// 处理字幕轨道信息}}设置 logo 叠加//libvlc_video_set_logo_int(vlc_mediaPlayer, libvlc_logo_enable, 1);//libvlc_video_set_logo_string(vlc_mediaPlayer, libvlc_logo_file, "D:\\2.png");libvlc_video_set_logo_int(vlc_mediaPlayer, libvlc_logo_position, libvlc_position_top_left);//libvlc_video_set_logo_int(vlc_mediaPlayer, libvlc_logo_x, 100);//libvlc_video_set_logo_int(vlc_mediaPlayer, libvlc_logo_y, 0);//libvlc_video_set_logo_int(vlc_mediaPlayer, libvlc_logo_opacity, 255);//libvlc_video_set_logo_int(vlc_mediaPlayer, libvlc_logo_repeat, 1);创建并设置水印文本//libvlc_video_set_marquee_int(vlc_mediaPlayer, libvlc_marquee_Enable, 1);//libvlc_video_set_marquee_int(vlc_mediaPlayer, libvlc_marquee_Position, libvlc_position_center);//libvlc_video_set_marquee_int(vlc_mediaPlayer, libvlc_marquee_Refresh, 2000);//libvlc_video_set_marquee_int(vlc_mediaPlayer, libvlc_marquee_Size, 24);//libvlc_video_set_marquee_string(vlc_mediaPlayer, libvlc_marquee_Text, "这里是水印文本");libvlc_video_set_marquee_int(w->vlc_mediaPlayer, libvlc_marquee_Timeout, 5000);//libvlc_video_set_marquee_int(vlc_mediaPlayer, libvlc_marquee_Opacity, 255); // 不透明//获取事件管理器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::slotActionTriggered(QAction *action)
{if (!vlc_mediaPlayer)return;if (action == m_default)libvlc_video_set_aspect_ratio(vlc_mediaPlayer,m_defalutRate);else if(action == m_16_9)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "16:9");else if (action == m_4_3)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "4:3");else if (action == m_1_1)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "1:1");else if (action == m_16_10)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "16:10");else if (action == m_2_21_1)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "221:100");else if (action == m_2_35_1)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "235:100");else if (action == m_2_38_1)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "238:100");else if (action == m_5_4)libvlc_video_set_aspect_ratio(vlc_mediaPlayer, "5:4");action->setIcon(QIcon(":/image/images/point.png"));m_preAspectRatio->setIcon(QIcon());m_preAspectRatio = action;
}void showWidget::slotCropActionTriggered(QAction *action)
{if (!vlc_mediaPlayer)return;if (action == m__cropDefault)libvlc_video_set_crop_geometry(vlc_mediaPlayer, m_defalutCrop);else if (action == m__crop16_10)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "16:10");else if (action == m__crop16_9)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "16:9");else if (action == m__crop4_3)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "4:3");else if (action == m__crop1_85_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "185:100");else if (action == m__crop2_21_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "221:100");else if (action == m__crop2_35_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "235:100");else if (action == m__crop2_39_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "239:100");else if (action == m__crop5_3)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "5:3");else if (action == m__crop5_4)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "5:4");else if (action == m__crop1_1)libvlc_video_set_crop_geometry(vlc_mediaPlayer, "1:1");action->setIcon(QIcon(":/image/images/point.png"));m_preCrop->setIcon(QIcon());m_preCrop = action;
}//事件回调
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;}
}void showWidget::initMenu()
{//总菜单m_menu = new QMenu(this);m_video = m_menu->addAction("视频");//视频菜单m_videoMenu = new QMenu(this);m_scaleAction = m_videoMenu->addAction("缩放");m_aspectRatioAction = m_videoMenu->addAction("宽高比");m_cropAction = m_videoMenu->addAction("裁剪");m_video->setMenu(m_videoMenu);//宽高比菜单m_aspectRatioMenu = new QMenu(this);m_aspectRatioAction->setMenu(m_aspectRatioMenu);//设置宽高比菜单m_default = m_aspectRatioMenu->addAction(QIcon(":/image/images/point.png"), "默认");m_16_9 = m_aspectRatioMenu->addAction("16:9");m_4_3 = m_aspectRatioMenu->addAction("4:3");m_1_1 = m_aspectRatioMenu->addAction("1:1");m_16_10 = m_aspectRatioMenu->addAction("16:10");m_2_21_1 = m_aspectRatioMenu->addAction("2.21:1");m_2_35_1 = m_aspectRatioMenu->addAction("2.35:1");m_2_38_1 = m_aspectRatioMenu->addAction("2.38:1");m_5_4 = m_aspectRatioMenu->addAction("5:4");m_preAspectRatio = m_default;m_group = new QActionGroup(this);m_group->addAction(m_default);m_group->addAction(m_16_9);m_group->addAction(m_4_3);m_group->addAction(m_1_1);m_group->addAction(m_16_10);m_group->addAction(m_2_21_1);m_group->addAction(m_2_35_1);m_group->addAction(m_2_38_1);m_group->addAction(m_5_4);connect(m_group, &QActionGroup::triggered, this, &showWidget::slotActionTriggered);//设置裁剪菜单m_cropMenu = new QMenu(this);m_cropAction->setMenu(m_cropMenu);m__cropDefault = m_cropMenu->addAction(QIcon(":/image/images/point.png"), "默认");m__crop16_10 = m_cropMenu->addAction("16:10");m__crop16_9 = m_cropMenu->addAction("16:9");m__crop4_3 = m_cropMenu->addAction("4:3");m__crop1_85_1 = m_cropMenu->addAction("1.85:1");m__crop2_21_1 = m_cropMenu->addAction("2.21:1");m__crop2_35_1 = m_cropMenu->addAction("2.35:1");m__crop2_39_1 = m_cropMenu->addAction("2.39:1");m__crop5_3 = m_cropMenu->addAction("5:3");m__crop5_4 = m_cropMenu->addAction("5:4");m__crop1_1 = m_cropMenu->addAction("1:1");m_preCrop = m__cropDefault;m_cropGroup = new QActionGroup(this);m_cropGroup->addAction(m__cropDefault);m_cropGroup->addAction(m__crop16_10);m_cropGroup->addAction(m__crop16_9);m_cropGroup->addAction(m__crop4_3);m_cropGroup->addAction(m__crop1_85_1);m_cropGroup->addAction(m__crop2_21_1);m_cropGroup->addAction(m__crop2_35_1);m_cropGroup->addAction(m__crop2_39_1);m_cropGroup->addAction(m__crop5_3);m_cropGroup->addAction(m__crop5_4);m_cropGroup->addAction(m__crop1_1);connect(m_cropGroup, &QActionGroup::triggered, this, &showWidget::slotCropActionTriggered);
}

更多参考:

libVLC 事件机制-CSDN博客

libVLC windows开发环境搭建-CSDN博客

https://sunnnnnn666.blog.csdn.net/article/details/136854500

libVLC 元数据-CSDN博客

libVLC 添加图片和文本水印-CSDN博客

https://sunnnnnn666.blog.csdn.net/article/details/136920169

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

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

相关文章

[网鼎杯2018]Unfinish 两种方法 -----不会编程的崽

网鼎杯太喜欢搞二次注入了吧。上次是无列名盲注&#xff0c;这次又是二次注入盲注。。。不知道方法还是挺难的。哎&#xff0c;网鼎嘛&#xff0c;能理解透彻就很强了。能自己做出来那可太nb了。 又是熟悉的登录框。不知道这是第几次看见网鼎杯的登录框了。后台扫描一下&#x…

『Apisix入门篇』从零到一掌握Apache APISIX:架构解析与实战指南

&#x1f4e3;读完这篇文章里你能收获到&#xff1a; &#x1f310; 深入Apache APISIX架构&#xff1a; 从Nginx到OpenResty&#xff0c;再到etcd&#xff0c;一站式掌握云原生API网关的构建精髓&#xff0c;领略其层次化设计的魅力。 &#x1f50c; 核心组件全解析&#xff…

【嵌入式学习】Qtday03.26

一、思维导图 二、练习 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }void Widget::on_login_btn_clicked() {if(ui->…

OC对象 - Block解决循环引用

文章目录 OC对象 - Block解决循环引用前言1. 循环引用示例1.1 分析 2. 解决思路3. ARC下3.1 __weak3.2 __unsafe_unretained3.3 __block 4. MRC下4.1 __unsafe_unretain....4.1 __block 5. 总结5.1 ARC下5.2 MRC下 OC对象 - Block解决循环引用 前言 本章将会通过一个循环引用…

flask_restful的基本使用

优势&#xff1a; Flask-Restful 是一个专门用来写 restful api 的一个插件。 使用它可以快速的集成restful api 接口功能。 在系统的纯api 的后台中&#xff0c;这个插件可以帮助我们节省很多时间。 缺点&#xff1a; 如果在普通的网站中&#xff0c;这个插件就没有优势了&…

测试环境搭建整套大数据系统(十二:挂载磁盘到hadoop环境)

一&#xff1a;链接硬盘 将硬盘连接到计算机的 SATA 接口或 USB 接口&#xff0c;并确保硬盘通电并处于可用状态。 二&#xff1a;查看硬盘信息 sudo fdisk -l三&#xff1a;创建分区 gdisk /dev/vbd重新扫描磁盘 partprobe /dev/vdb格式化磁盘 mkfs.ext4 /dev/vdb2查看磁…

前端学习之css基本网格布局

网格布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>网格布局</title><style>.a{/* grid网格布局 */display: grid;width: 400px;height: 400px;border: 1px solid red;/* 设置当前…

iOS开发之SwiftUI

iOS开发之SwiftUI 在iOS开发中SwiftUI与Objective-C和Swift不同&#xff0c;它采用了声明式语法&#xff0c;相对而言SwiftUI声明式语法简化了界面开发过程&#xff0c;减少了代码量。 由于SwiftUI是Apple推出的界面开发框架&#xff0c;从iOS13开始引入&#xff0c;Apple使用…

我在京东做数据分析,一位京东数据分析师的工作日常

有人说&#xff1a;“种下一棵树最好的时间是十年前&#xff0c;其次是现在”。任何时候&#xff0c;我们都应该抓住机遇&#xff0c;说不定就是改变你现状的一个机会。 2020年&#xff0c;我在疫情得到控制后&#xff0c;面试入职京东大数据组&#xff0c;截止目前&#xff0…

获取高德安全码SHA1

高德开发者平台上给的三种方法 获取安全码SHA1&#xff0c;这里我自己使用的是第三种方法。 1、通过Eclipse编译器获取SHA1 使用 adt 22 以上版本&#xff0c;可以在 eclipse 中直接查看。 Windows&#xff1a;依次在 eclipse 中打开 Window -> Preferances -> Androi…

flask_restful结合蓝图使用

在蓝图中&#xff0c;如果使用 Flask_RESTful &#xff0c; 创建 Api 对象的时候&#xff0c;传入蓝图对象即可&#xff0c;不再是传入 app 对象 /user/__init__.py from flask.blueprints import Blueprintuser_bp Blueprint(user,__name__)from user import views /user…

word文件如何转PDF格式?word转PDF的方法

在当今数字化时代&#xff0c;文档格式的转换已成为日常生活和工作中不可或缺的一部分。其中&#xff0c;将Word文档转换为PDF格式更是受到了广大用户的青睐。本文将详细介绍Word转PDF的方法&#xff0c;帮助读者轻松实现文档格式的转换&#xff0c;并探讨转换过程中的注意事项…

工业互联网下的增强现实

工业互联网下的增强现实 1、 概述 增强现实&#xff08;Augmented Reality&#xff0c;简称AR&#xff09;&#xff0c;增强现实技术也被称为扩增现实&#xff0c;AR增强现实技术是促使真实世界信息和虚拟世界信息内容之间综合在一起的较新的技术内容&#xff0c;其将原本在现…

【浅尝C++】类和对象第二弹=>类的6个默认成员函数/运算符重载详谈

&#x1f3e0;专栏介绍&#xff1a;浅尝C专栏是用于记录C语法基础、STL及内存剖析等。 &#x1f6a9;一些备注&#xff1a;之前的文章有点杂乱&#xff0c;这里将前面的知识点重新组织了&#xff0c;避免了过多冗余的废话。 &#x1f3af;每日努力一点点&#xff0c;技术变化看…

Appium Inspector 展示设备当前页面

定位元素需要使用appium inspector&#xff0c;之前每次都是从登录页开始&#xff0c;后来发现连接设备的时候只需要去掉appPackage、appActivity即可。 { "platformName": "Android", "platformVersion": "6", "deviceNa…

35.网络游戏逆向分析与漏洞攻防-游戏网络通信数据解析-登录成功数据包内容分析

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;34.登录数据包的…

LGBM算法 原理

简介 GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型&#xff0c;其主要思想是利用弱分类器&#xff08;决策树&#xff09;迭代训练以得到最优模型&#xff0c;该模型具有训练效果好、不易过拟合等优点。GBDT不仅在工业界应用广泛&#xff0c;通常被…

伪装目标检测之注意力CBAM:《Convolutional Block Attention Module》

论文地址&#xff1a;link 代码&#xff1a;link 摘要 我们提出了卷积块注意力模块&#xff08;CBAM&#xff09;&#xff0c;这是一种简单而有效的用于前馈卷积神经网络的注意力模块。给定一个中间特征图&#xff0c;我们的模块依次推断沿着两个独立维度的注意力图&#xff…

10.2024

使用选择排序将{2,9,5,0,1,3,6,8}排序 代码&#xff1a; public class 第十题 {public static void main(String[] args) {int a[]{2,9,5,0,1,3,6,8};int begin0;int enda.length-1;while (begin<end){int mina[begin];int tbegin;for (int ibegin;i<end;i){if(min>…

Selenium 自动化 —— 定位页面元素

更多内容请关注我的 Selenium 自动化 专栏&#xff1a; 入门和 Hello World 实例使用WebDriverManager自动下载驱动Selenium IDE录制、回放、导出Java源码浏览器窗口操作切换浏览器窗口 使用 Selenium 做自动化&#xff0c;我们不仅仅是打开一个网页&#xff0c;这只是万里长…