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

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. 用于拖动&#xff0c;缩放的工具类 “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&#xff08;You Only Look Once&#xff09;是一种目标检测算法。 一、主要特点 1. 速度快&#xff1a;YOLO 能够快速处理图像&#xff0c;实现实时目标检测。与其他一些目标检测算法相比&#xff0c;它在处理速度上具有明显优势&#xff0c;可以满足对实时性要求较高的应…...

传输层 II(TCP协议——协议的特点、报文段、连接管理)【★★★★】

&#xff08;★★&#xff09;代表非常重要的知识点&#xff0c;&#xff08;★&#xff09;代表重要的知识点。 一、TCP 协议的特点 TCP 是在不可靠的 IP 层之上实现的可靠的数据传输协议&#xff0c;它主要解决传输的可靠、有序、无丢失和不重复问题。TCP 是 TCP/IP 体系中非…...

质量小议47 - AI写用例

试着用AI写测试用例 AI替代基础性工作&#xff0c;帮助人思考&#xff0c;将会是更全面、更细致 时替代还是辅助 提问&#xff1a;密码输入框 测试用例评价指标- 功能性 - 可靠性 - 易用性 - 效率- 可维护性 - 可移植性基本思路 - 输入&#xff1a;遵从设计逻辑 和 系…...

etcd 集群搭建与测试指南

etcd 集群搭建与测试指南 一、容器搭建 1. 拉取 etcd 镜像 首先&#xff0c;需要从 Docker Hub 拉取 etcd 的镜像&#xff1a; docker pull quay.io/coreos/etcd:v3.3.12. 创建自定义网络 为了设置容器的固定 IP&#xff0c;需要创建一个自定义网络&#xff1a; docker n…...

写毕业论文用什么软件?分享6款好用的AI论文写作软件网站

撰写毕业论文是一项既重要又具挑战性的任务&#xff0c;尤其是在当今数字化时代&#xff0c;AI写作工具已经成为大学生撰写毕业论文的重要辅助手段。这些工具不仅能够提高写作效率&#xff0c;还能帮助学生生成高质量的文稿。以下是六款备受推荐的AI写毕业论文软件&#xff0c;…...

【技术解析】wx.request 封装:优化小程序网络请求的最佳实践

在当今的小程序开发领域&#xff0c;网络请求是构建动态应用的核心。微信小程序提供的 wx.request API 虽然强大&#xff0c;但在面对复杂业务逻辑时&#xff0c;其直接使用方式可能会带来一系列问题。本文将深入探讨封装 wx.request 的必要性&#xff0c;并提供一套实用的封装…...

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#设计模式之访问者模式

总目录 前言 在软件构建过程中&#xff0c;由于需求的改变&#xff0c;某些类层次结构中常常需要增加新的行为&#xff0c;如果直接在基类中做这样的更改&#xff0c;将会给子类带来很繁重的变更负担&#xff0c;甚至破坏原有设计。如何在不更改类层次结构的前提下&#xff0c…...

一次RPC调用过程是怎么样的?

注册中心 RPC&#xff08;Remote Procedure Call&#xff09;翻译成中文就是 {远程过程调用}。RPC 框架起到的作用就是为了实现&#xff0c;调用远程方法时&#xff0c;能够做到和调用本地方法一样&#xff0c;让开发人员更专注于业务开发&#xff0c;不用去考虑网络编程等细节…...

鸭脖变“刺客”,啃不起了

撰文&#xff5c;ANGELICA 编辑&#xff5c;ANGELICA 审核&#xff5c;烨 Lydia 声明&#xff5c;图片来源网络。日晞研究所原创文章&#xff0c;如需转载请留言申请开白。 你有多久没吃卤味了&#xff1f; 2020年之后&#xff0c;人们对于几大卤味巨头的关注度正在下降。 …...

力扣 —— 删除有序数组中的重复项

题目思路 两个指针&#xff0c;一个是游标的功能&#xff0c;负责遍历整个数组&#xff0c;一个是定位器的功能&#xff0c;如果有相等的则表示定位器目前指向的元素是重复的&#xff0c;定位器不动&#xff0c;等待游标往下找到不重复的数填充进来&#xff0c;因为游标会遍历…...

rmdir :删除空文件夹

一、命令简介 在 Linux 系统中&#xff0c;rmdir​ 命令用于删除空目录&#xff08;文件夹&#xff09;。 ‍ 二、命令参数 rmdir 目录‍ 三、命令示例 删除名为 dir1​ 的空目录&#xff1a; rmdir dir1删除多个空目录&#xff1a; rmdir dir1 dir2 dir3注意事项&#xf…...

网络爬虫Request静态页面数据获取

在现代 Web 开发中,HTTP 请求(Request)是与服务器进行通信的核心操作。无论是在前端还是后端开发中,数据的获取、传递以及处理都离不开请求的应用。特别是在静态页面的数据获取中,使用请求可以将页面变得更加动态和互动,从而大大提升用户体验,使得页面内容更加丰富和灵活…...

网页聊天——测试报告——Selenium自动化测试

一&#xff0c;项目概括 1.1 项目名称 网页聊天 1.2 测试时间 2024.9 1.3 编写目的 对编写的网页聊天项目进行软件测试活动&#xff0c;揭示潜在问题&#xff0c;总结测试经验 二&#xff0c;测试计划 2.1 测试环境与配置 服务器&#xff1a;云服务器 ubuntu_22 PC机&am…...

mysql5.7常用操作命令手册

文章目录 前言一、关闭mysql服务1.mha节点,关闭MHA高可用2.主节点&#xff0c;摘掉vip&#xff0c;停掉mysql服务3.从节点&#xff0c;停掉mysql服务 二、启动mysql1.启动数据库顺序2.主节点&#xff0c;登陆数据库检查主库状态,将主库改成读写状态3.从节点启动配置数据库&…...

前端组件库Element UI 的使用

一、准备工作 1.确保安装了开发软件 VS Code&#xff08;此处可查阅安装 VS Code教程&#xff09;&#xff0c;确保相关插件安装成功 2.安装Node.js 和创建Vue项目&#xff08;此处可查阅安装创建教程&#xff09; 3.成功在VS Code运行一个Vue项目&#xff08;此处可查阅运行…...

【C++ 基础数学 】2121. 2615相同元素的间隔之和|1760

本文涉及的基础知识点 基础数学 LeetCode2121. 相同元素的间隔之和 难度分&#xff1a;1760 令2165&#xff0c;和此题几乎相等。 给你一个下标从 0 开始、由 n 个整数组成的数组 arr 。 arr 中两个元素的 间隔 定义为它们下标之间的 绝对差 。更正式地&#xff0c;arr[i] 和…...

从手动测试菜鸟,到自动化测试老司机,实现自动化落地

虽然许多伙伴是一个测试老人了&#xff0c;但是基本上所有的测试经验都停留在手工测试方面&#xff0c;对于自动化测试方面的实战经验少之又少。 其实&#xff0c;究其原因&#xff1a;一方面是&#xff0c;自动化方面不求上进&#xff0c;觉得会手工测试就可以了&#xff0c;自…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

CppCon 2015 学习:Simple, Extensible Pattern Matching in C++14

什么是 Pattern Matching&#xff08;模式匹配&#xff09; ❝ 模式匹配就是一种“描述式”的写法&#xff0c;不需要你手动判断、提取数据&#xff0c;而是直接描述你希望的数据结构是什么样子&#xff0c;系统自动判断并提取。❞ 你给的定义拆解&#xff1a; ✴ Instead of …...

vxe-table vue 表格复选框多选数据,实现快捷键 Shift 批量选择功能

vxe-table vue 表格复选框多选数据&#xff0c;实现快捷键 Shift 批量选择功能 查看官网&#xff1a;https://vxetable.cn 效果 代码 通过 checkbox-config.isShift 启用批量选中,启用后按住快捷键和鼠标批量选取 <template><div><vxe-grid v-bind"gri…...