Qt无边框窗口拖拽和阴影

先看下效果:

在这里插入图片描述

说明

自定义窗口控件的无边框,窗口事件由于没有系统自带边框,无法实现拖拽拉伸等事件的处理,一种方法就是重新重写主窗口的鼠标事件,一种时通过nativeEvent事件处理。重写事件相对繁琐,我们这里推荐nativeEvent处理。注意后续我们在做win平台的进程通信,也会用到它!

  • 我们这里使用的是:nativeEvent

软件用到的样式表,这里就不展示了,大家可以自行调整!

关键点说明

QPainterPath

QPainterPath类提供一个容器,可以用来创建图形并且重复使用。绘制器路径是由许多图形构建基块(如矩形、椭圆形、直线和曲线)组成的对象。构建基块可以连接在封闭的子路径中,例如作为矩形或椭圆。封闭路径具有重合的起点和终点。或者它们可以作为未闭合的子路径独立存在,例如直线和曲线。

抗锯齿

  1. 抗锯齿是一种常见的图形处理技术,用于减少在显示器上呈现的图像中出现的锯齿状边缘。
    抗锯齿技术通过在边缘周围添加额外的像素来平滑边缘,从而减少锯齿状边缘。这种技术基于亚像素级别的渲染,它将颜色逐渐混合到边缘像素的周围像素中,使得边缘更加平滑。
  2. 打开抗锯齿可以使图像更加平滑,尤其是在呈现锐利直线或曲线时。这种技术可以减少锯齿状边缘,使得图像更加清晰,更加真实。特别是在高分辨率屏幕上,抗锯齿可以使得字体更加易读,图像更加细腻。
  3. 虽然抗锯齿可以使图像更加平滑,但在某些情况下,关闭抗锯齿可能更加合适。关闭抗锯齿可以提高图像处理速度。
  4. 这里我们基于Qt绘图框架用的是:
  • setRenderHint(QPainter::Antialiasing, true); //打开抗锯齿
  • setRenderHint(QPainter::Antialiasing, false); //关闭抗锯齿

具体实现

CDlgComBase,无边框窗口,带阴影,支持拖拽,注意:

  • 该实现方案不支持存在多个显示屏的情况!
  • 该实现方案仅支持win平台!

实现无边框带阴影的窗口代码,下面的代码供大家参考:

DlgComBase.h

#pragma once
#include "DlgShadow.h"
#include "FrameComTitleBar.h"
#include <QVBoxLayout>

class CDlgComBase : public CDlgShadow
{
	Q_OBJECT

public:
	CDlgComBase(QWidget *parent = 0, bool bCenterDlg = true, bool bHasTitleBar = true);
	~CDlgComBase();

	void SetWindowsTitle(const QString& strTitle, bool bCheckPos = false);

	// 显示隐藏按钮
	void ShowMinBtn(bool bShow);
	void ShowMaxBtn(bool bShow);
	void ShowCloseBtn(bool bShow);
	void ShowSettingBtn(bool bShow);
	
	void ShowMaximized();
	
	void SetTitleBarObjectName(QString strObjectName);
	void SetHeadBarHeight(int nHeight);

protected:
	virtual bool IsCaption(int nXPos, int nYPos);
	QWidget* GetCenterWidget() { return &m_frameCenter; }
	virtual void OnNcLBtnDbClick(int nXPos, int nYPos);

protected slots:
	void OnTimerCenter();

private:
	CFrameComTitleBar		m_frameComTitleBar;
	QVBoxLayout				m_vBoxLayout;
	QFrame					m_frameCenter;
	bool					m_bHasTitleBar;
};


DlgComBase.cpp

#include "DlgComBase.h"
#include <QTimer>

CDlgComBase::CDlgComBase(QWidget *parent, bool bCenterDlg, bool bHasTitleBar)
: CDlgShadow(parent), m_frameComTitleBar(this), m_frameCenter(this), m_bHasTitleBar(bHasTitleBar)
{
	m_frameComTitleBar.setObjectName("framComTitleBar");
	m_frameComTitleBar.setFixedHeight(GetHeadBarHeight());

	int nShadowLen = GetShadowLen();
	m_vBoxLayout.setContentsMargins(nShadowLen, nShadowLen, nShadowLen, nShadowLen);
	m_vBoxLayout.setSpacing(0);
	if (m_bHasTitleBar)
	{
		m_vBoxLayout.addWidget(&m_frameComTitleBar);
	}
	
	m_vBoxLayout.addWidget(&m_frameCenter);

	m_frameCenter.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	setLayout(&m_vBoxLayout);

	if (bCenterDlg)
		QTimer::singleShot(10, this, SLOT(OnTimerCenter()));
}

CDlgComBase::~CDlgComBase()
{

}

void CDlgComBase::SetWindowsTitle(const QString& strTitle, bool bCheckPos)
{
	m_strTitle = strTitle;
	m_frameComTitleBar.SetWindowsTitle(strTitle, bCheckPos);
	setWindowTitle(strTitle);
}

void CDlgComBase::ShowMinBtn(bool bShow)
{
	m_frameComTitleBar.ShowMinBtn(bShow);
}

void CDlgComBase::ShowMaxBtn(bool bShow)
{
	SetHasMaxFun(bShow);
	m_frameComTitleBar.ShowMaxBtn(bShow);
}

void CDlgComBase::ShowCloseBtn(bool bShow)
{
	m_frameComTitleBar.ShowCloseBtn(bShow);
}

void CDlgComBase::ShowSettingBtn(bool bShow)
{
	m_frameComTitleBar.ShowSettingBtn(bShow);
}

bool CDlgComBase::IsCaption(int nXPos, int nYPos)
{
	QWidget* pChild = childAt(nXPos, nYPos);
	if (pChild == NULL)
	{
		ADD_LOGD("CDlgComBase::IsCaption() return true");
		return true;
	}

	if (pChild == &m_frameComTitleBar || pChild == m_frameComTitleBar.GetTitleLabel())
	{
		ADD_LOGD("CDlgComBase::IsCaption() return true");
		return true;
	}

	ADD_LOGD("CDlgComBase::IsCaption() return false");
	return false;
}

void CDlgComBase::SetTitleBarObjectName(QString strObjectName)
{
	m_frameComTitleBar.setObjectName(strObjectName);
}

void CDlgComBase::OnTimerCenter()
{
	CenterInParent((QWidget*)parent());
}

void CDlgComBase::SetHeadBarHeight(int nHeight)
{
	m_frameComTitleBar.setFixedHeight(nHeight);
	CDlgShadow::SetHeadBarHeight(nHeight);
}

void CDlgComBase::ShowMaximized()
{
	m_frameComTitleBar.ShowMaximized();
	CDlgShadow::ShowMaximized();
}

void CDlgComBase::OnNcLBtnDbClick(int nXPos, int nYPos)
{
	if (m_bHasMaxFun)
		m_frameComTitleBar.ShowMaxRestoreBtn(m_bMaximized);
	CDlgShadow::OnNcLBtnDbClick(nXPos, nYPos);
}

DlgShadow.h

#ifndef SHADOWDLG_H
#define SHADOWDLG_H
#include <QDialog>
#include <QMouseEvent>

class CDlgShadow : public QDialog
{
	Q_OBJECT

public:
	CDlgShadow(QWidget *parent = 0);
	~CDlgShadow();

	void HideDlg();
	void ShowDlg();
	void SetDlgBkColor(QColor& clrDlgBk);
	void CenterInParent(QWidget* pWidget);
	void SetResizeable(bool bOn) { m_bResizeable = bOn; }
	virtual void OnBtnSettingClicked(QPoint& ptBtnBottom);
	virtual void OnBtnMinClicked();
	virtual void OnBtnMaxClicked();
	virtual void OnBtnRestoreClicked();
	virtual void OnBtnCloseClicked();
	virtual bool OnProHotKey(int nFsModifiers, int nVk);
	virtual void OnMsgEndSession();

	void ShowMaximized();

protected:
	void paintEvent(QPaintEvent* event);
	void keyPressEvent(QKeyEvent* event);
	int GetShadowLen() { return m_nShadowLen; }
	int GetHeadBarHeight() { return m_nHeadBarHeight; }
	void SetHeadBarHeight(int nHeight);
	void SetHasMaxFun(bool bHasMaxFun) { m_bHasMaxFun = bHasMaxFun; }
	bool nativeEvent(const QByteArray& eventType, void* pMessage, long* pResult);
	virtual bool IsCaption(int nXPos, int nYPos);
	virtual void OnNcLBtnDbClick(int nXPos, int nYPos);
	virtual void OnKeyReturnPress();
	virtual void OnKeyEscapePress();
	virtual void OnNcLBtnClick();
	void closeEvent(QCloseEvent *event);

protected:
	int					m_nFrameLen;		// 边框宽度,单位:像素
	int					m_nShadowLen;		// 阴影宽度,单位:像素
	int					m_nHeadBarHeight;	// 标题栏高度
	bool				m_bHasMaxFun;
	bool				m_bMaximized;
	bool				m_bNcLBtnClk;
	bool				m_bHideDlg;
	QString				m_strTitle;			// 调试时使用
	bool				m_bHotKey;			// 处理快捷键功能

private:
	QRect				m_rectDlg;
	QColor				m_clrDlgBk;
	bool				m_bResizeable;
};

#endif // SHADOWDLG_H

DlgShadow.cpp

#include "DlgShadow.h"
#include <QPainter>
#include <qmath.h>
#include <QApplication>
#include <QDesktopWidget>
#include <Windows.h>

CDlgShadow::CDlgShadow(QWidget *parent)
	: QDialog(parent)
{
	setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog | Qt::WindowMinimizeButtonHint);
	setAttribute(Qt::WA_TranslucentBackground);
	
	m_nFrameLen = 10;
	m_nShadowLen = 6;
	m_nHeadBarHeight = 36;
	m_bMaximized = false;
	m_bHasMaxFun = true;
	m_clrDlgBk = QColor(255, 255, 255);
	m_bResizeable = true;
	m_bNcLBtnClk = false;
	m_bHideDlg = false;
	m_bHotKey = false;
}

CDlgShadow::~CDlgShadow()
{

}

void CDlgShadow::paintEvent(QPaintEvent* event)
{
	QPainterPath path;
	path.setFillRule(Qt::WindingFill);
	path.addRoundedRect(m_nShadowLen, m_nShadowLen, width() - 2 * m_nShadowLen, height() - 2 * m_nShadowLen, 2, 2);

	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing, true);
	painter.fillPath(path, QBrush(m_clrDlgBk));

	QColor color(0, 0, 0, 50);
	for (int i = 0; i < m_nShadowLen; i++)
	{
		QPainterPath pathShadow;
		pathShadow.setFillRule(Qt::WindingFill);
		pathShadow.addRoundedRect(m_nShadowLen - i, m_nShadowLen - i, width() - (m_nShadowLen - i) * 2, height() - (m_nShadowLen - i) * 2, 2 + i, 2 + i);
		int nAlpha = 50 - qSqrt(i) * 25;
		if (nAlpha < 0)
			nAlpha = 0;
		color.setAlpha(nAlpha);
		painter.setPen(color);
		painter.drawPath(pathShadow);
	}

	painter.setRenderHint(QPainter::Antialiasing, false);
	painter.fillPath(path, QBrush(m_clrDlgBk));
	QDialog::paintEvent(event);
}

void CDlgShadow::OnBtnMinClicked()
{
	showMinimized();
}

void CDlgShadow::OnBtnMaxClicked()
{
	m_bMaximized = true;
	m_rectDlg = geometry();
	setGeometry(-m_nShadowLen, -m_nShadowLen, QApplication::desktop()->availableGeometry().width() + m_nShadowLen * 2,
		QApplication::desktop()->availableGeometry().height() + m_nShadowLen * 2);
}

void CDlgShadow::OnBtnRestoreClicked()
{
	m_bMaximized = false;
	setFixedHeight(QWIDGETSIZE_MAX);
	setGeometry(m_rectDlg);
}

void CDlgShadow::SetDlgBkColor(QColor& clrDlgBk)
{
	m_clrDlgBk = clrDlgBk;
}

void CDlgShadow::SetHeadBarHeight(int nHeight)
{
	m_nHeadBarHeight = nHeight; 
}

bool CDlgShadow::IsCaption(int nXPos, int nYPos)
{
	if (childAt(nXPos, nYPos) == 0)
	{
		ADD_LOGD("CDlgShadow::IsCaption() return true");
		return true;
	}
	else
	{
		ADD_LOGD("CDlgShadow::IsCaption() return false");
		return false;
	}
}

bool CDlgShadow::nativeEvent(const QByteArray& eventType, void* pMessage, long* pResult)
{
	ADD_LOGD(QString("CDlgShadow::nativeEvent in"));

	if (m_bHideDlg)
	{
		ADD_LOGD(QString("CDlgShadow::nativeEvent out"));
		return QDialog::nativeEvent(eventType, pMessage, pResult);
	}

	const MSG* pMsg = static_cast<MSG*>(pMessage);
	if (pMsg->message == WM_NCHITTEST)
	{
		RECT rect;
		SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
		int nWin32Width = rect.right - rect.left;
		int nWin32Height = rect.bottom - rect.top;
		int nQtWidth = QApplication::desktop()->availableGeometry().width();
		int nQtHeight = QApplication::desktop()->availableGeometry().height();
		int nMsgX = ((int)(short)LOWORD(pMsg->lParam)) * nQtWidth / nWin32Width;
		int nMsgY = ((int)(short)HIWORD(pMsg->lParam)) * nQtHeight / nWin32Height;
		int xPos = nMsgX - frameGeometry().x();
		int yPos = nMsgY - frameGeometry().y();
		if (IsCaption(xPos, yPos))
		{
			*pResult = HTCAPTION;
		}
		else
		{
			ADD_LOGD(QString("CDlgShadow::nativeEvent out, WM_NCHITTEST pResult:%1").arg(*pResult));
			return false;
		}

		if (!m_bResizeable)
		{
			if (*pResult == HTCAPTION)
			{
				ADD_LOGD(QString("CDlgShadow::nativeEvent out, WM_NCHITTEST pResult:%1").arg(*pResult));
				return true;
			}

			ADD_LOGD(QString("CDlgShadow::nativeEvent out, WM_NCHITTEST pResult:%1").arg(*pResult));
			return QDialog::nativeEvent(eventType, pMessage, pResult);
		}

		if (xPos > 0 && xPos < m_nFrameLen)
			*pResult = HTLEFT;

		if (xPos >(width() - m_nFrameLen) && xPos < (width() - 0))
			*pResult = HTRIGHT;

		if (yPos > 0 && yPos < m_nFrameLen)
			*pResult = HTTOP;

		if (yPos >(height() - m_nFrameLen) && yPos < (height() - 0))
			*pResult = HTBOTTOM;

		if (xPos > 0 && xPos < m_nFrameLen && yPos > 0 && yPos < m_nFrameLen)
			*pResult = HTTOPLEFT;

		if (xPos >(width() - m_nFrameLen) && xPos < (width() - 0) && yPos > 0 && yPos < m_nFrameLen)
			*pResult = HTTOPRIGHT;

		if (xPos > 0 && xPos < m_nFrameLen && yPos >(height() - m_nFrameLen) && yPos < (height() - 0))
			*pResult = HTBOTTOMLEFT;

		if (xPos >(width() - m_nFrameLen) && xPos < (width() - 0) && yPos >(height() - m_nFrameLen) && yPos < (height() - 0))
			*pResult = HTBOTTOMRIGHT;

		ADD_LOGD(QString("CDlgShadow::nativeEvent out, WM_NCHITTEST pResult:%1").arg(*pResult));
		return true;
	}
	else if (pMsg->message == WM_NCLBUTTONDBLCLK)
	{
		int xPos = ((int)(short)LOWORD(pMsg->lParam)) - frameGeometry().x();
		int yPos = ((int)(short)HIWORD(pMsg->lParam)) - frameGeometry().y();
		OnNcLBtnDbClick(xPos, yPos);
		ADD_LOGD(QString("CDlgShadow::nativeEvent out, WM_NCLBUTTONDBLCLK"));
		return true;
	}
	else if (pMsg->message == WM_NCLBUTTONDOWN)
	{
		if (m_bNcLBtnClk)
		{
			OnNcLBtnClick();
		}
	}
	else if (pMsg->message == WM_HOTKEY)
	{
		if (m_bHotKey)
		{
			UINT nFuModifiers = (UINT)LOWORD(pMsg->lParam);  // 模式
			UINT nVirtKey = (UINT)HIWORD(pMsg->lParam);     // 键值
			if (OnProHotKey(nFuModifiers, nVirtKey))
			{
				ADD_LOGD(QString("CDlgShadow::nativeEvent out, WM_HOTKEY"));
				return true;
			}
		}
	}
	else if (pMsg->message == WM_ENDSESSION)
	{
		ADD_LOGD(QStringLiteral("截获关机指令1"));
		OnMsgEndSession();
	}

	ADD_LOGD(QString("CDlgShadow::nativeEvent out"));
	return QDialog::nativeEvent(eventType, pMessage, pResult);
}

void CDlgShadow::OnNcLBtnDbClick(int nXPos, int nYPos)
{
	if (!m_bHasMaxFun)
		return;

	if (nYPos > m_nFrameLen + m_nHeadBarHeight)
		return;

	if (m_bMaximized)
	{
		OnBtnRestoreClicked();
	}
	else
	{
		OnBtnMaxClicked();
	}
}

void CDlgShadow::CenterInParent(QWidget* pWidget)
{
	int nXPos = 0;
	int nYPos = 0;
	if (pWidget == NULL)
	{
		nXPos = (QApplication::desktop()->width() - width()) / 2;
		nYPos = (QApplication::desktop()->height() - height()) / 2;
	}
	else
	{
		QWidget* pParent = (QWidget*)pWidget->parent();
// 		if (pParent != NULL)
// 		{
// 			//QPoint ptGloba = pWidget->mapToGlobal(QPoint(0, 0));
// 			nXPos = /*ptGloba.x() + */(pWidget->width() - width()) / 2;
// 			nYPos = /*ptGloba.y() + */(pWidget->height() - height()) / 2;
// 		}
// 		else
		{
			QPoint ptGloba = pWidget->mapToGlobal(QPoint(0, 0));
			nXPos = ptGloba.x() + (pWidget->width() - width()) / 2;
			nYPos = ptGloba.y() + (pWidget->height() - height()) / 2;
		}
	}
	move(nXPos, nYPos);
}

void CDlgShadow::keyPressEvent(QKeyEvent* event)
{
	if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return/* || event->key() == Qt::Key_Space*/)
	{
		OnKeyReturnPress();
		event->accept();
	}
	else if (event->key() == Qt::Key_Escape)
	{
		OnKeyEscapePress();
		event->ignore();
	}
}


void CDlgShadow::OnKeyReturnPress()
{
	//accept();
}

void CDlgShadow::OnKeyEscapePress()
{
	//reject();
}

void CDlgShadow::OnBtnCloseClicked()
{
	reject();
}

void CDlgShadow::OnBtnSettingClicked(QPoint& ptBtnBottom)
{

}

void CDlgShadow::OnNcLBtnClick()
{

}

void CDlgShadow::HideDlg()
{
	m_bHideDlg = true;
	setWindowOpacity(0);
}

void CDlgShadow::ShowDlg()
{
	setWindowOpacity(1);
	m_bHideDlg = false;
}

void CDlgShadow::closeEvent(QCloseEvent *event)
{
	event->ignore();
	OnBtnCloseClicked();
}

bool CDlgShadow::OnProHotKey(int nFsModifiers, int nVk)
{
	return false;
}

void CDlgShadow::OnMsgEndSession()
{

}

void CDlgShadow::ShowMaximized()
{
	m_bMaximized = true;
	int nXPos = (QApplication::desktop()->availableGeometry().width() - (1273 + 11)) / 2;
	int nYPos = (QApplication::desktop()->availableGeometry().height() - (878 + 11)) / 2;
	int nMaxHeight = QApplication::desktop()->availableGeometry().height() + m_nShadowLen * 2;
	//setFixedHeight(nMaxHeight);
	setFixedHeight(QWIDGETSIZE_MAX);

	m_rectDlg = QRect(nXPos, nYPos, (1273 + 11), (878 + 11));
	setGeometry(-m_nShadowLen, -m_nShadowLen, QApplication::desktop()->availableGeometry().width() + m_nShadowLen * 2,
		QApplication::desktop()->availableGeometry().height() + m_nShadowLen * 2);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2.3_8 多生产者-多消费者问题

2.3_8 多生产者-多消费者问题 实现思路 semaphore mutex1; //实现互斥访问盘子(缓冲区) semaphore apple0; //盘子中有几个苹果 semaphore orange0; //盘子中有几个橘子 semaphore plate 1; //盘子中还可以放多少个水果dad(){while(1){准备一个苹果;P(plate);P(mutex);把苹果放…

网络相关知识

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、相关工具3.1 network profiler/ In…

休息日的思考与额外题——链表

文章目录 前言链表知识点 一、 92. 反转链表 II二、21. 合并两个有序链表总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招&#xff0c;计划二刷完卡子哥的刷题计划&#xff0c;加油&#xff01; 二刷决定精刷了&#xff0c;于是参加了卡子哥的刷题班&#xff0c;训练…

构建知识图谱:从技术到实战的完整指南

目录 一、概述二、知识图谱的基础理论定义与分类核心组成历史与发展 三、知识获取与预处理数据源选择数据清洗实体识别 四、知识表示方法知识表示模型RDFOWL属性图模型 本体构建关系提取与表示 五、知识图谱构建技术图数据库选择Neo4jArangoDB 构建流程数据预处理实体关系识别图…

详谈掼蛋两大类牌型

掼蛋中的10种牌型&#xff0c;总体上可以分为炸弹牌型系列和普通牌型两大类。炸弹牌型系列包括天王炸、同花顺和多头炸3大类&#xff1b;普通牌型系列包括单张、对子、三同张、三带二、顺子、三连对、连三张等7种牌型。 一、两类牌型的区别 炸弹牌型系列和普通牌型系列两大类有…

信创条件下的运维思考-驱动数字化转型,塑造企业未来之篇章

2024-01-14 12:59 发布于&#xff1a;山西省 运维信创&#xff1a;驱动数字化转型&#xff0c;塑造企业未来之篇章 随着信息技术的迅猛发展&#xff0c;数字化转型已成为企业生存和发展的必由之路。在数字化转型的过程中&#xff0c;运维作为企业IT的重要组成部分&#xff…

【安装指南】HBuilder X 下载、安装详细教程

目录 &#x1f33a;1. 概述 &#x1f33b;2. HBuilder X 安装包下载 &#x1f33c;3. 安装详细教程 &#x1f33a;1. 概述 HBuilder X 是一款由DCloud开发的基于Electron框架的集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于Web和移动应用程序的开发。以下是…

【自媒体实战】——公众号排版工具调研

公众号排版工具 壹伴 地址&#xff1a;https://yiban.io/ 网站 壹伴 (https://yiban.io/) 主要提供一个高效的微信编辑器&#xff0c;专门服务于公众号运营者。它包括了一系列工具和功能&#xff0c;旨在帮助用户更便捷地进行文章排版、图片编辑、素材寻找和消息回复等操作。…

web渗透测试-Server2225-(环境+解析)

1、访问目标IP,打开第1题,根据页面提示,将获取的flag提交。提交格式:flag{xxx}(提交花括号里面的字段) 给出了如上代码,很明显,flag在flag.php文件内。 REQUEST方法既可以接受GET方法,也可以接受POST方法,方便起见,我们选择GET方法。 eval函数 eval() 函数把字符串…

如何实现无公网ip远程SSH连接家中本地的树莓派

文章目录 如何通过 SSH 连接到树莓派步骤1. 在 Raspberry Pi 上启用 SSH步骤2. 查找树莓派的 IP 地址步骤3. SSH 到你的树莓派步骤 4. 在任何地点访问家中的树莓派4.1 安装 Cpolar4.2 cpolar进行token认证4.3 配置cpolar服务开机自启动4.4 查看映射到公网的隧道地址4.5 ssh公网…

防御保护第四次作业

防火墙的智能选路 就近选路 --- 我们希望在访问不同运营商的服务器是&#xff0c;通过对应运营商的链路。这样可以高 通信效率&#xff0c;避免绕路。 策略路由 -- PBR 传统的路由&#xff0c;仅基于数据包中的目标IP地址查找路由表。仅关心其目标&#xff0c;所以&#…

大模型:合成数据、安全挑战与知识注入

在如今这个快速发展的AI时代&#xff0c;大语言模型&#xff08;LLM&#xff09;的研究论文数量呈指数级增长&#xff0c;几乎到了人力无法一一阅读和消化的地步。然而&#xff0c;对这些研究成果的归纳和总结至关重要&#xff0c;因为它们描绘了LLM领域的未来发展轮廓。在近期…

变相体罚学生包括什么

有时候由于种种原因&#xff0c;一些老师可能会采用变相体罚的方式来对待学生&#xff0c;不仅会伤害学生的身心健康&#xff0c;还会影响学生的学习积极性和成绩。什么是变相体罚呢&#xff1f; 变相体罚是指不采用直接的身体惩罚方式&#xff0c;而是采用其他方式来惩罚学生…

3、css设置样式总结、节点、节点之间关系、创建元素的方式、BOM

一、css设置样式的方式总结&#xff1a; 对象.style.css属性 对象.className ‘’ 会覆盖原来的类 对象.setAttribut(‘style’,‘css样式’) 对象.setAttribute(‘class’,‘类名’) 对象.style.setProperty(css属性名,css属性值) 对象.style.cssText “css样式表” …

JMeter性能测试实战

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

基于YOLOv7算法和FLIR数据集的高精度实时红外行人目标检测系统(PyTorch+Pyside6+YOLOv7)

摘要&#xff1a;基于YOLOv7算法和FLIR数据集的高精度实时红外行人目标检测系统可用于日常生活中检测与定位自行车、汽车、狗和行人目标&#xff0c;此系统可完成对输入图片、视频、文件夹以及摄像头方式的目标检测与识别&#xff0c;同时本系统还支持检测结果可视化与导出。本…

数据库基础01-mysql和SQL语句

目录 一、关系型数据库 1.什么是关系型数据库 2.主要优点 二、SQL语句 1.简介&#xff1a; 2.SQL通用语法 3.SQL语法分类 4.DDL &#xff08;1&#xff09;查询库 &#xff08;2&#xff09;创建库 &#xff08;3&#xff09;删除库 &#xff08;4&#xff09;使用库…

Qt应用软件【协议篇】Modbus详细介绍

文章目录 概述Modbus 485协议概述在工业自动化中的应用 通信模式数据模型功能码 Modbus RTU示例 1&#xff1a;读取保持寄存器示例 2&#xff1a;写入单个线圈示例 3&#xff1a;写入多个保持寄存器报文传输 Modbus ASCII报文示例报文传输 Modbus TCP报文示例报文传输 概述 在…

在中国如何方便地使用GPT Plus?

一、背景 通过魔法&#xff0c;顺利登录ChatGPT&#xff0c;准备升级GPT Plus时&#xff0c;发现需要国外信用卡才能支付&#xff0c;这对大多数中国人来说是不方便的。在google搜索解决方案时&#xff0c;发现了WildCard平台&#xff0c;可以一键升级 GPT Plus (GPT-4)。将基…

浅谈隔离放大器

浅谈隔离放大器 定义&#xff1a;隔离放大器是将输入的电量信号或物理量信号通过一种技术手段处理后,隔离输出一组模拟量信号,这组模拟量信号是以标准的4-20mA/0-20mA/0-10mA/0-10V/0-5V/1-5V/2-10V/0-2.5V/0-20mA/0-10mA/0-10V/0-100mV/0-5V等信号,以便控制系统及仪器仪表设备…