QT 自定义可拖动缩放的无边框窗口,可用于mainmindow, widget
1. 用于拖动,缩放的工具类
“WindowControl.h”
#ifndef WINDOWCONTROL_H
#define WINDOWCONTROL_H#include <QObject>
#include <QRubberBand>
#include <QStyleOptionFocusRect>
#include <QStylePainter>class RubberBand;
class CursorPosCalculator;/*** 窗口控制类* 存储界面对应的数据集合,及是否可移动、可缩放属性* 进行缩放等相关操作*/
class WindowControl : public QObject {Q_OBJECTpublic:explicit WindowControl(QObject *parent = nullptr);~WindowControl();void activeWindow(QWidget *window); // 激活窗体void removeWindow(QWidget *window); // 移除窗口void setWindowMove(bool moveAble); // 窗体移动void setWindowResize(bool resizeAble); // 窗体缩放void setRubberBandOnMove(bool movable); // 设置橡皮筋移动void setRubberBandOnResize(bool resizable); // 设置橡皮筋缩放void handleWidgetEvent(QEvent *event); // 处理鼠标划过、按下、按下、释放、移动事件void updateRubberBandStatus(); // 更新橡皮筋状态protected:virtual bool eventFilter(QObject *obj,QEvent *event); // 事件过滤, 移动,缩放private:/** 状态 **/// QHash<QWidget*, WindowData*> windowDataHash; // 缓存要控制的窗口bool windowMoveAble; // 可以移动bool windowResizeAble; // 可以缩放bool windowRubberBandOnResize; // 可以橡皮筋移动bool windowRubberBandOnMove; // 可以橡皮筋缩放/** 窗口及其操作 **/RubberBand *m_pRubberBand; // 橡皮筋选择框QWidget *m_pWidget; // 被控制的窗口QPoint m_ptDragPos; // 拖动时坐标CursorPosCalculator *m_pressedMousePos;CursorPosCalculator *m_moveMousePos;bool m_bLeftButtonPressed; // 鼠标左键是否按下bool m_bCursorShapeChanged; // 鼠标形状是否改变bool m_bLeftButtonTitlePressed; // 标题区域是否按下鼠标Qt::WindowFlags m_windowFlags;void updateCursorShape(const QPoint &gMousePos); // 更新鼠标样式void resizeWidget(const QPoint &gMousePos); // 重置窗体大小void moveWidget(const QPoint &gMousePos); // 移动窗体void handleMousePressEvent(QMouseEvent *event); // 处理鼠标按下void handleMouseReleaseEvent(QMouseEvent *event); // 处理鼠标释放void handleMouseMoveEvent(QMouseEvent *event); // 处理鼠标移动void handleLeaveEvent(QEvent *event); // 处理鼠标离开void handleHoverMoveEvent(QHoverEvent *event); // 处理鼠标进入
};// ================================================================
/*** 窗口控制,*/
class WindowData {};// ==================================================================
/*** 自定义的橡皮筋选择框* @brief The RubberBand class*/
class RubberBand : public QRubberBand {public:RubberBand(Shape s, QWidget *p = nullptr) : QRubberBand(s, p) {QPalette palette;palette.setBrush(QPalette::WindowText, QBrush(Qt::lightGray));setPalette(palette); // 调色板应用到当前的橡皮筋对象上repaint();}protected:virtual void paintEvent(QPaintEvent *) {QStylePainter painter(this);QStyleOptionFocusRect option;option.initFrom(this);QPen pen;pen.setStyle(Qt::DashLine);pen.setWidth(1);pen.setColor(QColor(Qt::red));painter.setPen(pen);painter.drawControl(QStyle::CE_FocusFrame, option);}
};// ==================================================================
/*** 计算鼠标是否位于左、上、右、下、左上角、左下角、右上角、右下角*/class CursorPosCalculator {public:explicit CursorPosCalculator();void reset();void recalculate(const QPoint &globalMousePos, const QRect &frameRect);public:bool m_bOnEdges;bool m_bOnLeftEdge;bool m_bOnRightEdge;bool m_bOnTopEdge;bool m_bOnBottomEdge;bool m_bOnTopLeftEdge;bool m_bOnBottomLeftEdge;bool m_bOnTopRightEdge;bool m_bOnBottomRightEdge;static int m_nBorderWidth;static int m_nTitleHeight;
};#endif // WINDOWCONTROL_H
WindowControl.cpp
#include "utils/WindowControl.h"
#include "qcoreevent.h"#include <QMouseEvent>/*** @brief WindowControl::WindowControl*/
WindowControl::WindowControl(QObject *parent) : QObject(parent) {// 初始化状态windowMoveAble = true;windowResizeAble = true;windowRubberBandOnMove = false;windowRubberBandOnResize = false;m_pressedMousePos = new CursorPosCalculator;m_moveMousePos = new CursorPosCalculator;
}WindowControl::~WindowControl() {m_pWidget->setMouseTracking(false); // 禁用鼠标跟踪m_pWidget->setWindowFlags(m_windowFlags); // 还原窗口标志m_pWidget->setAttribute(Qt::WA_Hover, false); // 禁用鼠标指针悬停事件delete m_pRubberBand;m_pRubberBand = NULL;delete m_pressedMousePos;m_pressedMousePos = NULL;delete m_moveMousePos;m_moveMousePos = NULL;
}bool WindowControl::eventFilter(QObject *obj, QEvent *event) {switch (event->type()) {case QEvent::MouseMove:case QEvent::HoverMove:case QEvent::MouseButtonPress:case QEvent::MouseButtonRelease:case QEvent::Leave: {if (obj == m_pWidget) {handleWidgetEvent(event);return true;}}default:return QObject::eventFilter(obj, event);}
}void WindowControl::activeWindow(QWidget *window) {m_pWidget = window;window->installEventFilter(this); // 安装事件过滤器m_bLeftButtonPressed = false;m_bCursorShapeChanged = false;m_bLeftButtonTitlePressed = false;m_pRubberBand = NULL;m_windowFlags = m_pWidget->windowFlags();m_pWidget->setMouseTracking(true); // 鼠标追踪m_pWidget->setAttribute(Qt::WA_Hover, true); // 启用鼠标指针悬停事件updateRubberBandStatus();
}void WindowControl::removeWindow(QWidget *window) {if (m_pWidget) {delete this;}
}void WindowControl::setWindowMove(bool moveAble) { windowMoveAble = moveAble; }void WindowControl::setWindowResize(bool resizeAble) { windowResizeAble = resizeAble; }void WindowControl::setRubberBandOnMove(bool movable) {windowRubberBandOnMove = movable;updateRubberBandStatus();
}void WindowControl::setRubberBandOnResize(bool resizable) {windowRubberBandOnResize = resizable;updateRubberBandStatus();
}void WindowControl::updateRubberBandStatus() {if (windowRubberBandOnResize || windowRubberBandOnMove) {if (NULL == m_pRubberBand) {m_pRubberBand = new RubberBand(QRubberBand::Rectangle);}} else {delete m_pRubberBand;m_pRubberBand = NULL;}
}void WindowControl::handleWidgetEvent(QEvent *event) {switch (event->type()) {default:break;case QEvent::MouseButtonPress:handleMousePressEvent(static_cast<QMouseEvent *>(event));break;case QEvent::MouseButtonRelease:handleMouseReleaseEvent(static_cast<QMouseEvent *>(event));break;case QEvent::MouseMove:handleMouseMoveEvent(static_cast<QMouseEvent *>(event));break;case QEvent::Leave:handleLeaveEvent(event);break;case QEvent::HoverMove:handleHoverMoveEvent(static_cast<QHoverEvent *>(event));break;}
}void WindowControl::updateCursorShape(const QPoint &gMousePos) {// 检查全屏或最大化状态if (m_pWidget->isFullScreen() || m_pWidget->isMaximized()) {if (m_bCursorShapeChanged) {m_pWidget->unsetCursor(); // 光标设置为默认}return;}m_moveMousePos->recalculate(gMousePos, m_pWidget->frameGeometry());if (m_moveMousePos->m_bOnTopLeftEdge || m_moveMousePos->m_bOnBottomRightEdge) {m_pWidget->setCursor(Qt::SizeFDiagCursor); // 对角线大小调整光标m_bCursorShapeChanged = true;} else if (m_moveMousePos->m_bOnTopRightEdge || m_moveMousePos->m_bOnBottomLeftEdge) {m_pWidget->setCursor(Qt::SizeBDiagCursor); // 反对角线大小调整光标m_bCursorShapeChanged = true;} else if (m_moveMousePos->m_bOnLeftEdge || m_moveMousePos->m_bOnRightEdge) {m_pWidget->setCursor(Qt::SizeHorCursor); // 水平调整大小光标m_bCursorShapeChanged = true;} else if (m_moveMousePos->m_bOnTopEdge || m_moveMousePos->m_bOnBottomEdge) {m_pWidget->setCursor(Qt::SizeVerCursor); // 垂直调整大小光标m_bCursorShapeChanged = true;} else {if (m_bCursorShapeChanged) {m_pWidget->unsetCursor(); // 恢复默认m_bCursorShapeChanged = false;}}
}void WindowControl::resizeWidget(const QPoint &gMousePos) {QRect origRect;if (windowRubberBandOnResize)origRect = m_pRubberBand->frameGeometry();elseorigRect = m_pWidget->frameGeometry();int left = origRect.left();int top = origRect.top();int right = origRect.right();int bottom = origRect.bottom();origRect.getCoords(&left, &top, &right, &bottom);// int minWidth = m_pWidget->minimumWidth();// int minHeight = m_pWidget->minimumHeight();int minWidth = 40;int minHeight = 40;if (m_pressedMousePos->m_bOnTopLeftEdge) {left = gMousePos.x();top = gMousePos.y();} else if (m_pressedMousePos->m_bOnBottomLeftEdge) {left = gMousePos.x();bottom = gMousePos.y();} else if (m_pressedMousePos->m_bOnTopRightEdge) {right = gMousePos.x();top = gMousePos.y();} else if (m_pressedMousePos->m_bOnBottomRightEdge) {right = gMousePos.x();bottom = gMousePos.y();} else if (m_pressedMousePos->m_bOnLeftEdge) {left = gMousePos.x();} else if (m_pressedMousePos->m_bOnRightEdge) {right = gMousePos.x();} else if (m_pressedMousePos->m_bOnTopEdge) {top = gMousePos.y();} else if (m_pressedMousePos->m_bOnBottomEdge) {bottom = gMousePos.y();}QRect newRect(QPoint(left, top), QPoint(right, bottom));if (newRect.isValid()) {if (minWidth > newRect.width()) {if (left != origRect.left())newRect.setLeft(origRect.left());elsenewRect.setRight(origRect.right());}if (minHeight > newRect.height()) {if (top != origRect.top())newRect.setTop(origRect.top());elsenewRect.setBottom(origRect.bottom());}if (windowRubberBandOnResize) {m_pRubberBand->setGeometry(newRect);} else {m_pWidget->setGeometry(newRect);}}
}void WindowControl::moveWidget(const QPoint &gMousePos) {if (windowRubberBandOnMove) {m_pRubberBand->move(gMousePos - m_ptDragPos);} else {m_pWidget->move(gMousePos - m_ptDragPos);}
}void WindowControl::handleMousePressEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton) {m_bLeftButtonPressed = true;m_bLeftButtonTitlePressed = event->pos().y() < 30;QRect frameRect = m_pWidget->frameGeometry();QRect moveRect(frameRect.x(), frameRect.y(), frameRect.width(), 30);m_pressedMousePos->recalculate(event->globalPos(), frameRect);m_ptDragPos = event->globalPos() - frameRect.topLeft();if (m_pressedMousePos->m_bOnEdges) {if (windowRubberBandOnResize) {m_pRubberBand->setGeometry(frameRect);m_pRubberBand->show();}} else if (windowRubberBandOnMove) {if (moveRect.contains(event->globalPos())) {m_pRubberBand->setGeometry(frameRect);m_pRubberBand->show();}}}
}void WindowControl::handleMouseReleaseEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton) {m_bLeftButtonPressed = false;m_bLeftButtonTitlePressed = false;m_pressedMousePos->reset();if (m_pRubberBand && m_pRubberBand->isVisible()) {m_pRubberBand->hide();m_pWidget->setGeometry(m_pRubberBand->geometry());}}
}void WindowControl::handleMouseMoveEvent(QMouseEvent *event) {if (m_bLeftButtonPressed) {if (windowResizeAble && m_pressedMousePos->m_bOnEdges) {resizeWidget(event->globalPos());} else if (windowMoveAble && m_bLeftButtonTitlePressed) {moveWidget(event->globalPos());}} else if (windowResizeAble) {updateCursorShape(event->globalPos());}
}void WindowControl::handleLeaveEvent(QEvent *event) {Q_UNUSED(event)if (!m_bLeftButtonPressed) {m_pWidget->unsetCursor();}
}void WindowControl::handleHoverMoveEvent(QHoverEvent *event) {if (windowResizeAble) {updateCursorShape(m_pWidget->mapToGlobal(event->pos())); // 局部坐标转全局屏幕坐标}
}// CursorPosCalculator==========================================int CursorPosCalculator::m_nBorderWidth = 5;
int CursorPosCalculator::m_nTitleHeight = 30;CursorPosCalculator::CursorPosCalculator() { reset(); }void CursorPosCalculator::reset() {m_bOnEdges = false;m_bOnLeftEdge = false;m_bOnRightEdge = false;m_bOnTopEdge = false;m_bOnBottomEdge = false;m_bOnTopLeftEdge = false;m_bOnBottomLeftEdge = false;m_bOnTopRightEdge = false;m_bOnBottomRightEdge = false;
}void CursorPosCalculator::recalculate(const QPoint &gMousePos, const QRect &frameRect) {int globalMouseX = gMousePos.x();int globalMouseY = gMousePos.y();int frameX = frameRect.x();int frameY = frameRect.y();int frameWidth = frameRect.width();int frameHeight = frameRect.height();m_bOnLeftEdge = (globalMouseX >= frameX && globalMouseX <= frameX + m_nBorderWidth);m_bOnRightEdge = (globalMouseX >= frameX + frameWidth - m_nBorderWidth && globalMouseX <= frameX + frameWidth);m_bOnTopEdge = (globalMouseY >= frameY && globalMouseY <= frameY + m_nBorderWidth);m_bOnBottomEdge = (globalMouseY >= frameY + frameHeight - m_nBorderWidth && globalMouseY <= frameY + frameHeight);m_bOnTopLeftEdge = m_bOnTopEdge && m_bOnLeftEdge;m_bOnBottomLeftEdge = m_bOnBottomEdge && m_bOnLeftEdge;m_bOnTopRightEdge = m_bOnTopEdge && m_bOnRightEdge;m_bOnBottomRightEdge = m_bOnBottomEdge && m_bOnRightEdge;m_bOnEdges = m_bOnLeftEdge || m_bOnRightEdge || m_bOnTopEdge || m_bOnBottomEdge;
}
2. 使用示例
定义基类:
#ifndef WINDOW_H
#define WINDOW_H#include <QMainWindow>/*** 自定义无边框mainwindow*/
class Window : public QMainWindow {Q_OBJECTpublic:Window(QWidget *parent = nullptr);~Window();private:void framelesshelperInit();
};#endif // WINDOW_H
#include "component/window.h"
#include "utils/WindowControl.h"Window::Window(QWidget *parent) : QMainWindow(parent) {resize(1200, 740);setWindowFlags(Qt::FramelessWindowHint);framelesshelperInit();
}Window::~Window() {}void Window::framelesshelperInit() {// this指的是要处理的窗体WindowControl *control = new WindowControl(this);control->activeWindow(this); //激活当前窗体control->setWindowMove(true); //设置窗体可移动control->setWindowResize(true); //设置窗体可缩放control->setRubberBandOnMove(true); //设置橡皮筋效果-可移动control->setRubberBandOnResize(true); //设置橡皮筋效果-可缩放
}
继承可拖动缩放的窗口:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include "component/window.h"#include <QMainWindow>class MainWindow : public Window {Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include <QLabel>MainWindow::MainWindow(QWidget *parent) : Window(parent) {resize(1200, 740);setWindowFlags(Qt::FramelessWindowHint);// 创建自定义标题栏QLabel *customTitleBar = new QLabel("自定义标题栏", this);customTitleBar->setStyleSheet("background-color: blue; color: white;");// 设置自定义标题栏setMenuWidget(customTitleBar);}MainWindow::~MainWindow() {}
使用:
#include "mainwindow.h"#include "component/window.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}
控制类引用自: https://blog.csdn.net/u012959478/article/details/140658545
上述测试工程代码: https://download.csdn.net/download/qq_51355375/89783077
相关文章:
QT 自定义可拖动缩放的无边框窗口,可用于mainmindow, widget
1. 用于拖动,缩放的工具类 “WindowControl.h” #ifndef WINDOWCONTROL_H #define WINDOWCONTROL_H#include <QObject> #include <QRubberBand> #include <QStyleOptionFocusRect> #include <QStylePainter>class RubberBand; class Curs…...
鸿蒙 OS 开发零基础快速入门教程
视频课程: 东西比较多, 这里主要分享一些代码和案例. 开关灯效果案例: 开灯 开关灯效果案例: 关灯 Column 和 Row 的基本用法 Entry Component struct Index {State message: string 张三;build() {// 一行内容Row() {// 一列内容Column() {// 文本内容Text(this.mess…...
yolo介绍
YOLO(You Only Look Once)是一种目标检测算法。 一、主要特点 1. 速度快:YOLO 能够快速处理图像,实现实时目标检测。与其他一些目标检测算法相比,它在处理速度上具有明显优势,可以满足对实时性要求较高的应…...
传输层 II(TCP协议——协议的特点、报文段、连接管理)【★★★★】
(★★)代表非常重要的知识点,(★)代表重要的知识点。 一、TCP 协议的特点 TCP 是在不可靠的 IP 层之上实现的可靠的数据传输协议,它主要解决传输的可靠、有序、无丢失和不重复问题。TCP 是 TCP/IP 体系中非…...
质量小议47 - AI写用例
试着用AI写测试用例 AI替代基础性工作,帮助人思考,将会是更全面、更细致 时替代还是辅助 提问:密码输入框 测试用例评价指标- 功能性 - 可靠性 - 易用性 - 效率- 可维护性 - 可移植性基本思路 - 输入:遵从设计逻辑 和 系…...
etcd 集群搭建与测试指南
etcd 集群搭建与测试指南 一、容器搭建 1. 拉取 etcd 镜像 首先,需要从 Docker Hub 拉取 etcd 的镜像: docker pull quay.io/coreos/etcd:v3.3.12. 创建自定义网络 为了设置容器的固定 IP,需要创建一个自定义网络: docker n…...
写毕业论文用什么软件?分享6款好用的AI论文写作软件网站
撰写毕业论文是一项既重要又具挑战性的任务,尤其是在当今数字化时代,AI写作工具已经成为大学生撰写毕业论文的重要辅助手段。这些工具不仅能够提高写作效率,还能帮助学生生成高质量的文稿。以下是六款备受推荐的AI写毕业论文软件,…...
【技术解析】wx.request 封装:优化小程序网络请求的最佳实践
在当今的小程序开发领域,网络请求是构建动态应用的核心。微信小程序提供的 wx.request API 虽然强大,但在面对复杂业务逻辑时,其直接使用方式可能会带来一系列问题。本文将深入探讨封装 wx.request 的必要性,并提供一套实用的封装…...
9.24 C++ 常成员,运算符重载
//my_string.cpp #include "my_string.h" #include <iostream> #include <cstring>using namespace std;My_string::My_string():size(15){this->ptr new char[size];this->ptr[0] \0; //表示串为空串this->len 0;}//有参构造My_…...
C#设计模式之访问者模式
总目录 前言 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为,如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。如何在不更改类层次结构的前提下,…...
一次RPC调用过程是怎么样的?
注册中心 RPC(Remote Procedure Call)翻译成中文就是 {远程过程调用}。RPC 框架起到的作用就是为了实现,调用远程方法时,能够做到和调用本地方法一样,让开发人员更专注于业务开发,不用去考虑网络编程等细节…...
鸭脖变“刺客”,啃不起了
撰文|ANGELICA 编辑|ANGELICA 审核|烨 Lydia 声明|图片来源网络。日晞研究所原创文章,如需转载请留言申请开白。 你有多久没吃卤味了? 2020年之后,人们对于几大卤味巨头的关注度正在下降。 …...
力扣 —— 删除有序数组中的重复项
题目思路 两个指针,一个是游标的功能,负责遍历整个数组,一个是定位器的功能,如果有相等的则表示定位器目前指向的元素是重复的,定位器不动,等待游标往下找到不重复的数填充进来,因为游标会遍历…...
rmdir :删除空文件夹
一、命令简介 在 Linux 系统中,rmdir 命令用于删除空目录(文件夹)。 二、命令参数 rmdir 目录 三、命令示例 删除名为 dir1 的空目录: rmdir dir1删除多个空目录: rmdir dir1 dir2 dir3注意事项…...
网络爬虫Request静态页面数据获取
在现代 Web 开发中,HTTP 请求(Request)是与服务器进行通信的核心操作。无论是在前端还是后端开发中,数据的获取、传递以及处理都离不开请求的应用。特别是在静态页面的数据获取中,使用请求可以将页面变得更加动态和互动,从而大大提升用户体验,使得页面内容更加丰富和灵活…...
网页聊天——测试报告——Selenium自动化测试
一,项目概括 1.1 项目名称 网页聊天 1.2 测试时间 2024.9 1.3 编写目的 对编写的网页聊天项目进行软件测试活动,揭示潜在问题,总结测试经验 二,测试计划 2.1 测试环境与配置 服务器:云服务器 ubuntu_22 PC机&am…...
mysql5.7常用操作命令手册
文章目录 前言一、关闭mysql服务1.mha节点,关闭MHA高可用2.主节点,摘掉vip,停掉mysql服务3.从节点,停掉mysql服务 二、启动mysql1.启动数据库顺序2.主节点,登陆数据库检查主库状态,将主库改成读写状态3.从节点启动配置数据库&…...
前端组件库Element UI 的使用
一、准备工作 1.确保安装了开发软件 VS Code(此处可查阅安装 VS Code教程),确保相关插件安装成功 2.安装Node.js 和创建Vue项目(此处可查阅安装创建教程) 3.成功在VS Code运行一个Vue项目(此处可查阅运行…...
【C++ 基础数学 】2121. 2615相同元素的间隔之和|1760
本文涉及的基础知识点 基础数学 LeetCode2121. 相同元素的间隔之和 难度分:1760 令2165,和此题几乎相等。 给你一个下标从 0 开始、由 n 个整数组成的数组 arr 。 arr 中两个元素的 间隔 定义为它们下标之间的 绝对差 。更正式地,arr[i] 和…...
从手动测试菜鸟,到自动化测试老司机,实现自动化落地
虽然许多伙伴是一个测试老人了,但是基本上所有的测试经验都停留在手工测试方面,对于自动化测试方面的实战经验少之又少。 其实,究其原因:一方面是,自动化方面不求上进,觉得会手工测试就可以了,自…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
