当前位置:首页 > 后端开发 > 正文内容

完成qt 窗口无边框拖拽

邻居的猫1个月前 (12-09)后端开发1956

无边框拖拽是参阅Qt实战6.全能的无边框窗口(FramelessWindow) - Qt小罗 - 博客园的文章,对其代码进行修正而来。

运用的是qt6 所以有或许里边一些关于坐标的类需求修正一下类型

代码运用的话,我是直接让widget承继于framlessWidget,下图是效果图

相比较,我将m_movePoint变成是m_pressPoint间隔鼠标的相对坐标;然后让m_bIsResizing的值由m_direction来判别是否要拉伸窗口,一起添加了一个通明的带边框的窗体border来完结预览移动而拉伸的状况,因为我将qt小罗的及时修正边框的方位和巨细改成延时,所以需求有个能预览的边框来观看。

只要由鼠标按下和松开来调用其他函数,例如鼠标按下要对一些变量进行从头设置避免前次操作的影响、判别是否要拉伸窗口和让border绑定父窗口显现出border。其他函数需求自己检查

关于移动窗口的话,需求对派生类进行多几步的操作

列子:topWidget和mainWidgetLeft都是页面的边际是我想在这些当地点击后能触发移动条件

void MainWidget::mousePressEvent(QMouseEvent* event)
{
    int topWidgetHeight = this->topWidget->height();
    int leftWidgetWidth = this->mainWidgetLeft->width();

    int x = event->x();
    int y = event->y();
    //  以上获取的数据是分别是契合条件的区域和鼠标的相对坐标
    // 判别是否契合窗口移动条件
    if (x <= leftWidgetWidth || y <= topWidgetHeight) {
        this->setMoveStatus(true);//true表明可以移动
    }

    FramelessWidget::mousePressEvent(event);
}
//framelessWidget.h

#pragma once

#include <QWidget>
class TransparentBorder;


class FramelessWidget : public QWidget
{
	Q_OBJECT
public:
		enum Direction {//鼠标处于哪个鸿沟
		BOTTOMRIGHT,
		TOPRIGHT,
		TOPLEFT,
		BOTTOMLEFT,
		RIGHT,
		DOWN,
		LEFT,
		UP,
		NONE
	};
	enum {//间隔鸿沟多少时改动鼠标款式
		MARGIN_MIN_SIZE = 0,
		MARGIN_MAX_SIZE = 4
	};
public:
	FramelessWidget(QWidget* parent = nullptr);
	~FramelessWidget();
	
	
	void setBorderColor(const QColor& color);


protected:
	bool event(QEvent* event) override;
	void leaveEvent(QEvent* event) override;
	void mousePressEvent(QMouseEvent* event) override;
	void mouseMoveEvent(QMouseEvent* event) override;
	void mouseReleaseEvent(QMouseEvent* event) override;
	//修正鼠标款式,且是否处于鸿沟
	void updateRegion(QMouseEvent* event);
	//修正巨细和方位,即geometry
	void resizeRegion(int marginTop, int marginBottom, int marginLeft, int marginRight);
	void createShadow();
	void maximizeWidget();
	void minimizeWidget();
	void restoreWidget();
	
	void setMoveStatus(bool status);

    void paintEvent(QPaintEvent* event) override;

private:
	bool m_bIsPressed;		//是否鼠标按下
	bool m_bIsResizing;		//是否要拉伸
	bool m_bIsDoublePressed;//没用到
	bool m_bIsMove;
	QPoint m_pressPoint;	//鼠标按下时的坐标
	QPoint m_pressPoint_initial;//没用到
	QPoint m_movePoint;		//鼠标移动了的相对坐标
	Direction m_direction;	//鼠标的状况即在哪个鸿沟


	QRect rect;				//用于寄存geometry
	TransparentBorder* border;

};

class TransparentBorder :public  QWidget {
public:
	TransparentBorder();
	~TransparentBorder();


	void resizeBorder(const QPoint& movePoint,FramelessWidget::Direction direction);
	void moveBorder(const QPoint& movePoint);

	void setParentRect(const QRect& rect);
	void setBorderColor(const QColor& color);
protected:

	void paintEvent(QPaintEvent* event) override;
	
private:
	QPoint marginOrigin;
	QRect parentRect;
	QColor borderColor;
};

cpp文件

#include "framelesswidget.h"
#include <QEvent>
#include <QMouseEvent>
#include <QRect>
#include <QApplication>
#include <QGraphicsDropShadowEffect>
#include <QtMath>
#include <QPen>
#include <QPainter>
#include <QPainterPath>
#include "model/data.h"

FramelessWidget::FramelessWidget(QWidget* parent)
	: QWidget(parent), m_bIsPressed(false), m_bIsResizing(false), m_bIsDoublePressed(false),m_bIsMove(false),
	m_direction(NONE)
{
	setWindowFlags(Qt::FramelessWindowHint);    //躲藏标题栏(无边框)
	setAttribute(Qt::WA_StyledBackground);      //启用款式布景制作
	//setAttribute(Qt::WA_TranslucentBackground); //布景通明
	setAttribute(Qt::WA_Hover);
	setAttribute(Qt::WA_StaticContents);
	this->setMinimumSize(50, 50);
	
	border = new TransparentBorder();//并没有让border挂在this下面,所以得析构时得delete
	border->hide();

}

FramelessWidget::~FramelessWidget()
{
	delete border;
}

bool FramelessWidget::event(QEvent* event)
{
	///
	// 使得移除窗口仍能进行鼠标移动的事情
	///
	if (event->type() == QEvent::HoverMove) {
		QHoverEvent* hoverEvent = static_cast<QHoverEvent*>(event);
		QMouseEvent mouseEvent(QEvent::MouseMove, hoverEvent->pos(),
			Qt::NoButton, Qt::NoButton, Qt::NoModifier);
		mouseMoveEvent(&mouseEvent);
		//LOG() << "hover move";
	}

	return QWidget::event(event);
}

void FramelessWidget::mousePressEvent(QMouseEvent* event)
{
	QWidget::mousePressEvent(event);
	if (event->button() == Qt::LeftButton) {
		m_bIsPressed = true;
		m_pressPoint = event->globalPos();//鼠标按下的肯定坐标
		m_movePoint = QPoint(0, 0);//使得前次移动的相对坐标清零

	}
	//*
	//假如m_direction不为NoNE 即 鼠标在窗口鸿沟 那么便是要进行窗口拉伸
	//*
	if (m_direction != NONE) {
		m_bIsResizing = true;
	}
	//因为运用的是 额定创立一个boder边框使得可以预览窗口的方位
	// 所以得让boder知道要绑定谁,且知道他的geometry
	if (m_bIsMove || m_bIsResizing) {
		border->setParentRect(geometry());
		border->show();//显现边框

	}
}

void FramelessWidget::mouseMoveEvent(QMouseEvent* event)
{

	QWidget::mouseMoveEvent(event);
	m_movePoint = event->globalPos() - m_pressPoint;
	//LOG() <<"m_bIsResizing"<< m_bIsResizing;
	//LOG() <<"m_bIsPressed"<< m_bIsPressed;
	
	//*
	//	鼠标没按下 且 不处于拉伸状况才来判别是不是在鸿沟
	//*
	if (windowState() != Qt::WindowMaximized && !m_bIsPressed && !m_bIsResizing) {
		updateRegion(event);
	}

//	LOG() << "width" << minimumWidth();
//	LOG() << "height" << minimumHeight();

	//*
	//	鼠标按下 但不处于拉伸状况
	//*
	if (m_bIsPressed && !m_bIsResizing) {
		border->moveBorder(m_movePoint);
	}
	//拉伸状况
	else if (m_bIsResizing) {
		border->resizeBorder(m_movePoint, m_direction);
	}



}

// 用于辨认是否是拉伸动作
void FramelessWidget::updateRegion(QMouseEvent* event)
{
	QRect mainRect = geometry();

	int marginTop = event->globalY() - mainRect.y();
	int marginBottom = mainRect.y() + mainRect.height() - event->globalY();
	int marginLeft = event->globalX() - mainRect.x();
	int marginRight = mainRect.x() + mainRect.width() - event->globalX();

	//LOG() << marginTop << "|" << marginBottom << "|" << marginLeft << "|" << marginRight;

	if (!m_bIsResizing && !m_bIsPressed) {
		if ((marginRight >= MARGIN_MIN_SIZE && marginRight <= MARGIN_MAX_SIZE)
			&& ((marginBottom <= MARGIN_MAX_SIZE) && marginBottom >= MARGIN_MIN_SIZE)) {
			m_direction = BOTTOMRIGHT;
			setCursor(Qt::SizeFDiagCursor);
		}
		else if ((marginTop >= MARGIN_MIN_SIZE && marginTop <= MARGIN_MAX_SIZE)
			&& (marginRight >= MARGIN_MIN_SIZE && marginRight <= MARGIN_MAX_SIZE)) {
			m_direction = TOPRIGHT;
			setCursor(Qt::SizeBDiagCursor);
		}
		else if ((marginLeft >= MARGIN_MIN_SIZE && marginLeft <= MARGIN_MAX_SIZE)
			&& (marginTop >= MARGIN_MIN_SIZE && marginTop <= MARGIN_MAX_SIZE)) {
			m_direction = TOPLEFT;
			setCursor(Qt::SizeFDiagCursor);
		}
		else if ((marginLeft >= MARGIN_MIN_SIZE && marginLeft <= MARGIN_MAX_SIZE)
			&& (marginBottom >= MARGIN_MIN_SIZE && marginBottom <= MARGIN_MAX_SIZE)) {
			m_direction = BOTTOMLEFT;
			setCursor(Qt::SizeBDiagCursor);
		}
		else if (marginBottom <= MARGIN_MAX_SIZE && marginBottom >= MARGIN_MIN_SIZE) {
			m_direction = DOWN;
			setCursor(Qt::SizeVerCursor);
		}
		else if (marginLeft <= MARGIN_MAX_SIZE - 1 && marginLeft >= MARGIN_MIN_SIZE - 1) {
			m_direction = LEFT;
			setCursor(Qt::SizeHorCursor);
		}
		else if (marginRight <= MARGIN_MAX_SIZE && marginRight >= MARGIN_MIN_SIZE) {
			m_direction = RIGHT;
			setCursor(Qt::SizeHorCursor);
		}
		else if (marginTop <= MARGIN_MAX_SIZE && marginTop >= MARGIN_MIN_SIZE) {
			m_direction = UP;
			setCursor(Qt::SizeVerCursor);
		}
		else {
			m_direction = NONE;
			setCursor(Qt::ArrowCursor);

		}
	}
	//LOG() << m_direction;

}

//对窗口进行巨细和方位进行设置
void FramelessWidget::resizeRegion(int marginTop, int marginBottom,
	int marginLeft, int marginRight)
{
	if (m_bIsPressed && m_bIsResizing) {
		//LOG() << "resize" << m_direction;
		switch (m_direction) {
		case BOTTOMRIGHT:
		{
			rect = geometry();
			rect.setBottomRight(rect.bottomRight() + m_movePoint);
			this->setGeometry(rect);
		}
		break;
		case TOPRIGHT:
		{
			rect = geometry();
			// 设置的宽度 小于 最小宽度 高度 小于 最小高度
			if (geometry().width() + m_movePoint.x() <= minimumWidth() && geometry().height() - m_movePoint.y() <= minimumHeight()) {
				rect.setRect(rect.x() ,
					rect.y() + rect.height() - minimumHeight(),
					minimumWidth(),
					minimumHeight());
				//LOG() << "1";
			}
			// 设置的宽度 小于 最小宽度 高度 大于 最小高度
			else if (geometry().width() + m_movePoint.x() <= minimumWidth() && geometry().height() - m_movePoint.y() > minimumHeight()) {
				rect.setRect(rect.x() ,
					rect.y() + m_movePoint.y(),
					minimumWidth(),
					rect.height() - m_movePoint.y());
				//LOG() << "2";
			}
			// 设置的宽度 大于 最小宽度 高度 小于 最小高度
			else if (geometry().height() - m_movePoint.y() <= minimumHeight() && geometry().width() + m_movePoint.x() > minimumWidth()) {
				rect.setRect(rect.x() ,
					rect.y() + rect.height() - minimumHeight(),
					rect.width() + m_movePoint.x(),
					minimumHeight());
				//LOG() << "3"<<rect;

			}
			// 设置的宽度 大于 最小宽度 高度 大于 最小高度
			else {
				rect.setTopRight(rect.topRight() + m_movePoint);
				//LOG() << "4";

			}


			this->setGeometry(rect);
		}
		break;
		case TOPLEFT:
		{
			rect = geometry();
			// 设置的宽度 小于 最小宽度 高度 小于 最小高度
			if (geometry().width() - m_movePoint.x() <= minimumWidth() && geometry().height() - m_movePoint.y() <= minimumHeight()) {
				rect.setRect(rect.x() +rect.width() -minimumWidth(),
					rect.y() + rect.height() -minimumHeight(),
					minimumWidth(),
					minimumHeight());
				//LOG() << "1";
			}
			// 设置的宽度 小于 最小宽度 高度 大于 最小高度
			else if (geometry().width() - m_movePoint.x() <= minimumWidth() && geometry().height() - m_movePoint.y() > minimumHeight()) {
				rect.setRect(rect.x() +rect.width() -minimumWidth() ,
					rect.y() + m_movePoint.y(),
					minimumWidth(),
					rect.height() - m_movePoint.y());
				//LOG() << "2";
			}
			// 设置的宽度 大于 最小宽度 高度 小于 最小高度
			else if (geometry().height() - m_movePoint.y() <= minimumHeight() && geometry().width() - m_movePoint.x() > minimumWidth()) {
				rect.setRect(rect.x() + m_movePoint.x(),
					rect.y() + rect.height() - minimumHeight(),
					rect.width() - m_movePoint.x(),
					minimumHeight());
				//LOG() << "3"<<rect;

			}
			// 设置的宽度 大于 最小宽度 高度 大于 最小高度
			else {
				rect.setTopLeft(rect.topLeft() + m_movePoint);
				//LOG() << "4";

			}


			this->setGeometry(rect);

		}
		break;
		case BOTTOMLEFT:
		{
			rect = geometry();
			// 设置的宽度 小于 最小宽度 高度 小于 最小高度
			if (geometry().width() - m_movePoint.x() <= minimumWidth() && geometry().height() + m_movePoint.y() <= minimumHeight()) {
				rect.setRect(rect.x() +rect.width() -minimumWidth(),
					rect.y(),
					minimumWidth(),
					minimumHeight());
				//LOG() << "1";
			}
			// 设置的宽度 小于 最小宽度 高度 大于 最小高度
			else if (geometry().width() - m_movePoint.x() <= minimumWidth() && geometry().height() + m_movePoint.y() > minimumHeight()) {
				rect.setRect(rect.x() +rect.width() -minimumWidth() ,
					rect.y(),
					minimumWidth(),
					rect.height() + m_movePoint.y());
				//LOG() << "2";
			}
			// 设置的宽度 大于 最小宽度 高度 小于 最小高度
			else if (geometry().height() + m_movePoint.y() <= minimumHeight() && geometry().width() - m_movePoint.x() > minimumWidth()) {
				rect.setRect(rect.x() + m_movePoint.x(),
					rect.y(),
					rect.width() - m_movePoint.x(),
					minimumHeight());
				//LOG() << "3"<<rect;

			}
			// 设置的宽度 大于 最小宽度 高度 大于 最小高度
			else {
				rect.setBottomLeft(rect.bottomLeft() + m_movePoint);
				//LOG() << "4";

			}


			this->setGeometry(rect);

		}
		break;
		case RIGHT:
		{
			rect = geometry();
			rect.setRight(rect.right() + m_movePoint.x());
			this->setGeometry(rect);
			//setFixedSize(rect.width(), rect.height());

		}
		break;
		case DOWN:
		{
			rect = geometry();
			rect.setBottom(rect.bottom() + m_movePoint.y());
			//rect.setHeight(rect.height() + m_movePoint.y());
			this->setGeometry(rect);
			//setFixedSize(rect.width(), rect.height());
			//LOG() << "down";
		}
		break;
		case LEFT:
		{
			if (geometry().width() - m_movePoint.x() < minimumWidth()) {
				rect = geometry();
				rect.setRect(rect.x() + rect.width() - minimumWidth(),
					rect.y() ,
					minimumWidth(),
					rect.height());
				this->setGeometry(rect);
			}
			else {

				rect = geometry();
				rect.setLeft(rect.left() + m_movePoint.x());
				//rect.setX(rect.width() - m_movePoint.x());
				this->setGeometry(rect);

				//setFixedSize(rect.width(), rect.height());
				//this->move(rect.x() + m_movePoint.x(), rect.y());
			}
		}
		break;
		case UP:
		{
			if (geometry().height() - m_movePoint.y() < minimumHeight()) {
				rect = geometry();
				rect.setRect(rect.x(),
					rect.y() + rect.height() - minimumHeight(),
					rect.width(),
					minimumHeight());
				this->setGeometry(rect);
			}
			else {
				rect = geometry();
				rect.setTop(rect.top() + m_movePoint.y());
				this->setGeometry(rect);
				//LOG() << "UP";
			}
			

		}
		break;
		default:
		{
		}
		break;
		}
	}
	else {
		m_bIsResizing = false;
		//当不在鸿沟必定得设置NONE,否则会导致在鸿沟后,下次不在鸿沟会被判别成拉伸状况
		m_direction = NONE;
	}
}

void FramelessWidget::mouseReleaseEvent(QMouseEvent* event)
{
	///
	//	鼠标松开 需求判别 是否处于拉伸状况需求修正窗口
	//			是否是窗口需求移动
	///
    QWidget::mouseReleaseEvent(event);
	//LOG() << m_direction;
	if (NONE != m_direction) {
		//LOG() << "resize";
		resizeRegion(0, 0, 0, 0);
	}
	// 鼠标松开,当鼠标按下的状况还没修正
	//	处于移动窗口的状况
	if (!m_bIsResizing && m_bIsPressed && m_bIsMove) {
		this->move(geometry().x() + m_movePoint.x(), geometry().y() + m_movePoint.y());
	}
	this->setMoveStatus(false);
	//LOG() << "1:" << geometry();

	// 修正鼠标的款式
	if (windowState() != Qt::WindowMaximized) {
		updateRegion(event);
	}

	//重置值,避免影响下次判别
    if (event->button() == Qt::LeftButton) {
        m_bIsPressed = false;
		m_bIsResizing = false;
		m_bIsDoublePressed = false;
		m_direction = NONE;
	}
	//完结 操作 撤销显现边框
	border->hide();

	//LOG() << "move_point" << m_movePoint;
	//LOG()<<"2:" << geometry();
}

void FramelessWidget::leaveEvent(QEvent *event)
{
   // m_bIsPressed = false;
   // m_bIsDoublePressed = false;
   // m_bIsResizing = false;

    QWidget::leaveEvent(event);
}

void FramelessWidget::createShadow()
{
    QGraphicsDropShadowEffect *shadowEffect = new QGraphicsDropShadowEffect(this);
    shadowEffect->setColor(Qt::black);
    shadowEffect->setOffset(0, 0);
    shadowEffect->setBlurRadius(13);
    this->setGraphicsEffect(shadowEffect);
}

void FramelessWidget::maximizeWidget()
{
  
    showMaximized();
}
void FramelessWidget::minimizeWidget()
{
	showMinimized();
}
void FramelessWidget::restoreWidget()
{
   
    showNormal();
}

void FramelessWidget::setMoveStatus(bool status)
{
	this->m_bIsMove = status;
}

void FramelessWidget::setBorderColor(const QColor& color)
{
	this->border->setBorderColor(color);
}


void FramelessWidget::paintEvent(QPaintEvent* event)
{

    QWidget::paintEvent(event);


}


TransparentBorder::TransparentBorder():
	QWidget(),marginOrigin(0,0),parentRect(0,0,0,0),borderColor(Qt::white)
{
	setWindowOpacity(1);
	this->setAttribute(Qt::WA_TranslucentBackground, true);//通明
	this->setWindowFlags(Qt::FramelessWindowHint);//无边框

}

TransparentBorder::~TransparentBorder()
{
}

//边框的巨细设置
void TransparentBorder::resizeBorder(const QPoint& m_movePoint, FramelessWidget::Direction direction)
{
	switch (direction) {
	case FramelessWidget::Direction::BOTTOMRIGHT:
		{
		LOG() << "BottomRight";
			QRect rect(parentRect);
			rect.setBottomRight(rect.bottomRight() + m_movePoint);
			this->setGeometry(rect);
		}
		break;
		case FramelessWidget::Direction::TOPRIGHT:
		{
			QRect rect(parentRect);
			rect.setTopRight(rect.topRight() + m_movePoint);
			this->setGeometry(rect);
		}
		break;
		case FramelessWidget::Direction::TOPLEFT:
		{
			QRect rect(parentRect);
			rect.setTopLeft(rect.topLeft() + m_movePoint);
			this->setGeometry(rect);
		}
		break;
		case FramelessWidget::Direction::BOTTOMLEFT:
		{
			QRect rect(parentRect);
			rect.setBottomLeft(rect.bottomLeft() + m_movePoint);
			this->setGeometry(rect);
		}
		break;
		case FramelessWidget::Direction::RIGHT:
		{
			QRect rect(parentRect);
			rect.setRight(rect.right() + m_movePoint.x());
			setGeometry(rect);

		}
		break;
		case FramelessWidget::Direction::DOWN:
		{
			//LOG() << "down";
			//LOG() << "parentRect:" << parentRect;
			QRect rect(parentRect);
			rect.setBottom(rect.bottom() + m_movePoint.y());
			//rect.setHeight(rect.height() + m_movePoint.y());
			setGeometry(rect);

		}
		break;
		case FramelessWidget::Direction::LEFT:
		{
			QRect rect(parentRect);
			rect.setLeft(rect.left() + m_movePoint.x());
			setGeometry(rect);

		}
		break;
		case FramelessWidget::Direction::UP:
		{
			QRect rect(parentRect);
			//rect.setHeight(rect.height() - m_movePoint.y());
			rect.setTop(rect.top() + m_movePoint.y());
			setGeometry(rect);
			//setFixedSize(rect.width(), rect.height());
			//LOG() << "UP";
			
		}
		break;
		default:
		{
		}
		break;
		}

}

//移动边框
void TransparentBorder::moveBorder(const QPoint& movePoint)
{
	this->move(parentRect.x()+movePoint.x(), parentRect.y()+movePoint.y());
}


//设置要绑定哪个窗口
void TransparentBorder::setParentRect(const QRect& rect)
{
	parentRect.setRect(rect.x(),rect.y(),rect.width(),rect.height());
	this->setGeometry(parentRect);

}

void TransparentBorder::setBorderColor(const QColor& color)
{
	borderColor = color;
}

// 烘托时画出出边框
void TransparentBorder::paintEvent(QPaintEvent *event)
{

	QRect rect = geometry();
	QPainter painter(this);
    painter.setBrush(QColor(9,151,247,1));//painter区域悉数的布景色
    painter.setPen(QPen(borderColor,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    painter.setCompositionMode(QPainter::CompositionMode_Difference);
    painter.drawRect(0,0,rect.width(),rect.height());

	//this->resize(parentRect.width(),parentRect.height());
}


扫描二维码推送至手机访问。

版权声明:本文由51Blog发布,如需转载请注明出处。

本文链接:https://www.51blog.vip/?id=199

分享给朋友:

“完成qt 窗口无边框拖拽” 的相关文章

Apollo功能及原理详解

Apollo功能及原理详解

前语 公司里边运用的装备中心是携程开源的Apollo,之前我只运用过Nacos,遂记载一下学习进程。 Apollo作业原理 模块介绍 上图便是Apollo的总体规划,从下往上挨个剖析: ConfigDB用于存储各种装备 Config Service供给装备的读取、推送等功用,服务对象是Apollo...

构建你的.NET Aspire解决方案

构建你的.NET Aspire解决方案

.NET Aspire 是一组功用强大的东西、模板和包,用于构建可调查的出产安排妥当运用程序。.NET Aspire 经过处理特定云原生问题的 NuGet 包调集供给。云原生运用程序一般由小型互连部分或微服务组成,而不是单个整体式代码库。云原生运用程序一般会耗费很多的服务,例如数据库、音讯收发和缓...

把握规划形式之工厂办法形式

把握规划形式之工厂办法形式

工厂办法形式 工厂办法形式(Factory Method Pattern)是一种创立型规划形式,它界说了一个用于创立方针的接口,但由子类决议要实例化的详细类。工厂办法形式将方针的创立托付给子类,然后完结了类的实例化推迟和高内聚低耦合的方针。 工厂办法形式的结构 工厂办法形式一般包含以下几个人物: P...

python代码大全,python免费版

1. Python 100例 菜鸟教程 提供了100个Python练习实例,涵盖了Python的基础语法、数据结构、函数、类、模块等知识点。每个实例都有代码和输出结果,适合Python初学者和进阶者学习和练习。 2. python代码库 云代码 收录常用代码片段,方便程序...

r语言聚类分析,方法、实例与技巧

1. Kmeans聚类:Kmeans是最常用的聚类算法之一,它将数据点分为K个簇,其中K是用户指定的。Kmeans的目标是最小化簇内数据点与簇中心之间的距离。2. 层次聚类:层次聚类是一种将数据点逐层合并或分裂的聚类方法。它构建一个树状结构,称为聚类树或树状图,用于表示数据点之间的相似性。3. 密度...

C语言编程软件,助力编程学习与开发

C语言编程软件,助力编程学习与开发

1. Visual Studio Code:这是一款轻量级但功能强大的源代码编辑器,支持多种编程语言,包括C语言。它具有丰富的扩展插件,可以轻松实现代码高亮、代码提示、调试等功能。适用于Windows、macOS和Linux系统。2. Eclipse:Eclipse是一个开源的集成开发环境(IDE)...