TouchGFX之文本区域

文本区域在屏幕上显示文本。 文本区域的文本在大小、颜色、自定义字体、动态文本等方面是完全可以配置的

#ifndef TOUCHGFX_TEXTAREA_HPP
#define TOUCHGFX_TEXTAREA_HPP
#include <touchgfx/Font.hpp>
#include <touchgfx/TextProvider.hpp>
#include <touchgfx/TypedText.hpp>
#include <touchgfx/Unicode.hpp>
#include <touchgfx/hal/Types.hpp>
#include <touchgfx/widgets/Widget.hpp>

namespace touchgfx
{
/* 文本区域 */
class TextArea : public Widget
{
public:
	/* 构造函数 */
	TextArea()
			: Widget(), typedText(TYPED_TEXT_INVALID), color(0), linespace(0), alpha(255), indentation(0), rotation(TEXT_ROTATE_0), wideTextAction(WIDE_TEXT_NONE), boundingArea()
	{
	}

	// 设置宽度,并重新计算文本区域的边界
	virtual void setWidth(int16_t width)
	{
		Widget::setWidth(width);
		boundingArea = calculateBoundingArea();
	}

	// 设置高度,并重新计算文本区域的边界
	virtual void setHeight(int16_t height)
	{
		Widget::setHeight(height);
		boundingArea = calculateBoundingArea();
	}

	/* 获取可以保证为实心的(不透明的)最大矩形 */
	virtual Rect getSolidRect() const
	{
		return Rect();
	}

	/* 设置文本颜色 */
	FORCE_INLINE_FUNCTION void setColor(colortype newColor)
	{
		color = newColor;
	}

	/* 获取文本颜色 */
	FORCE_INLINE_FUNCTION colortype getColor() const
	{
		return color;
	}

	/* 设置透明度 */
	virtual void setAlpha(uint8_t newAlpha)
	{
		alpha = newAlpha;
	}

	/* 获取透明度值 */
	uint8_t getAlpha() const
	{
		return alpha;
	}

	// 调整TextArea的y坐标,使文本的基线(而不是TextArea)位于指定的y值
	virtual void setBaselineY(int16_t baselineY)
	{
		setY(baselineY - getTypedText().getFont()->getBaseline());
	}

	// 调整TextArea的x和y坐标,使文本的基线位于指定的y值,x坐标将被用作TextArea的x坐标
	virtual void setXBaselineY(int16_t x, int16_t baselineY)
	{
		setX(x);
		setBaselineY(baselineY);
	}

	// 设置TextArea的行间距。设置更大的值将增加行之间的距离。可以设置负值使行(部分)重叠
	FORCE_INLINE_FUNCTION void setLinespacing(int16_t space)
	{
		linespace = space;
		boundingArea = calculateBoundingArea();
	}

	// 获取TextArea的行间距。如果没有设置行间距,则行间距为0
	FORCE_INLINE_FUNCTION int16_t getLinespacing() const
	{
		return linespace;
	}

	// 设置文本的缩进。这对于斜体字体非常有用,可以防止某些字符(如"j"和"g")在左侧下方延伸到前一个字符下面
	FORCE_INLINE_FUNCTION void setIndentation(uint8_t indent)
	{
		indentation = indent;
		boundingArea = calculateBoundingArea();
	}

	// 获取文本的缩进
	FORCE_INLINE_FUNCTION uint8_t getIndentation()
	{
		return indentation;
	}

	/* 获取文本对齐方式 */
	virtual Alignment getAlignment() const;

	/* 获取文本高度 */
	virtual int16_t getTextHeight() const;

	/* 获取文本宽度 */
	virtual uint16_t getTextWidth() const;

	// 绘制文本区域
	virtual void draw(const Rect& area) const;

	/* 设置文本资源。如果之前没有设置过大小,TextArea将被调整以适应新的TypedText */
	void setTypedText(const TypedText& t);

	/* 获取文本资源 */
	const TypedText& getTypedText() const
	{
		return typedText;
	}

	/* 设置文本的旋转角度 */ 
	FORCE_INLINE_FUNCTION void setRotation(const TextRotation textRotation)
	{
		rotation = textRotation;
		boundingArea = calculateBoundingArea();
	}

	/* 获取文本旋转角度 */
	TextRotation getRotation() const
	{
		return rotation;
	}

	/* 根据文本尺寸和旋转方向调整控件尺寸 */
	void resizeToCurrentText();

	/* 根据对齐方式、旋转方向和尺寸调整控件尺寸和位置以适应文本 */
	void resizeToCurrentTextWithAlignment();

	/* 根据文本高度和旋转方向调整文本尺寸以适应文本 */
	void resizeHeightToCurrentText();

	/* 根据文本高度调整和旋转方向文本尺寸和位置以适应文本 */
	void resizeHeightToCurrentTextWithRotation();

	// 设置文本行过宽时的处理方式。并重新计算文本边界区域
	// 默认情况下,只有当文本中存在手动插入的换行符时,文本行才会换行。  
	// 如果启用了换行,并且文本将占用比TextArea更多的行数,  
	// 则在最后一行的末尾添加一个省略号(通常为&hellip;)以表示某些文本被省略。  
	// 用于省略的字符取自文本样式表
	FORCE_INLINE_FUNCTION void setWideTextAction(WideTextAction action)
	{
		wideTextAction = action;
		boundingArea = calculateBoundingArea();
	}

	// 获取之前通过文本过宽处理方式
	WideTextAction getWideTextAction() const
	{
		return wideTextAction;
	}

	// 根据文本格式和可变参数计算文本所需的总高度。  
	// 格式字符串中的<placeholder>占位符数量必须与后面的可变参数数量相匹配
	virtual int16_t calculateTextHeight(const Unicode::UnicodeChar* format, ...) const;

	// 获取TypedText中的第一个占位符。  
	// 如果此文本区域有占位符,则返回指向第一个占位符的指针,否则返回0
	virtual const Unicode::UnicodeChar* getWildcard1() const
	{
		return 0;
	}

	// 获取TypedText中的第二个占位符。  
	// 如果此文本区域有两个占位符,则返回指向第二个占位符的指针,否则返回0
	virtual const Unicode::UnicodeChar* getWildcard2() const
	{
		return 0;
	}

	//内容重新绘制
	virtual void invalidateContent() const;

protected:
	/* 刚好报文文本的边界区域 */
	class BoundingArea
	{
		public:
			// 使用给定的包围矩形和包含的文本初始化BoundingArea类的新实例
			BoundingArea(const Rect& boundingRect, const Unicode::UnicodeChar* containedText)
					: rect(boundingRect), text(containedText)
			{
			}

			// 初始化一个默认为无效的BoundingArea类的新实例
			BoundingArea() : rect(Rect(0, 0, -1, -1)), text(0)
			{
			}

			// 获取包围矩形
			Rect getRect() const
			{
				return rect;
			}

			// 查询包围区域是否有效
			bool isValid(const Unicode::UnicodeChar* currentText) const
			{
				return (rect.height >= 0 && rect.width >= 0 && text == currentText);
			}

		private:
			Rect rect;
			const Unicode::UnicodeChar* text;
	};

	// 计算此文本区域的最小包围矩形,并将其与包含的文本相关联,以获得包围区域。  
	// 注意:根据对齐方式和旋转角度调整包围矩形
	virtual TextArea::BoundingArea calculateBoundingArea() const;

	TypedText typedText;                //文本资源
	colortype color;                    //颜色
	int16_t linespace;                  //行间距
	uint8_t alpha;                      //透明度
	uint8_t indentation;                //缩进
	TextRotation rotation;              //旋转角度
	WideTextAction wideTextAction;      //过宽处理
	static const uint16_t newLine = 10; //换行值
	BoundingArea boundingArea;          //此文本区域的包围区域
};

}

#endif
#include <stdarg.h>
#include <touchgfx/hal/HAL.hpp>
#include <touchgfx/lcd/LCD.hpp>
#include <touchgfx/widgets/TextArea.hpp>

namespace touchgfx
{
/* 获取文本对齐方式 */
Alignment TextArea::getAlignment() const
{
	if(typedText.hasValidId())
	{
		return typedText.getAlignment();
	}

	return LEFT;
}

/* 获取文本高度:考虑行数 */
int16_t TextArea::getTextHeight() const
{
	return typedText.hasValidId() ? calculateTextHeight(typedText.getText(), getWildcard1(), getWildcard2()) : 0;
}

/* 获取文本宽度 */
uint16_t TextArea::getTextWidth() const
{
	return typedText.hasValidId() ? typedText.getFont()->getStringWidth(typedText.getTextDirection(), typedText.getText(), getWildcard1(), getWildcard2()) : 0;
}

// 绘制文本区域
void TextArea::draw(const Rect& area) const
{
	if (typedText.hasValidId())
	{
		/* 边界矩形 */
		Rect rectToDraw = area;
		if(typedText.hasValidId() && boundingArea.isValid(typedText.getText()))
		{
			rectToDraw &= boundingArea.getRect();
		}
		
		if (!rectToDraw.isEmpty())
		{
			/* 绘制指定的Unicode字符串。在新行处换行 */
			const Font* fontToDraw = typedText.getFont();
			if (fontToDraw != 0)
			{
				const LCD::StringVisuals visuals(fontToDraw, color, alpha, getAlignment(), linespace, rotation, typedText.getTextDirection(), indentation, wideTextAction);
				HAL::lcd().drawString(getAbsoluteRect(), rectToDraw, visuals, typedText.getText(), getWildcard1(), getWildcard2());
			}
		}
	}
}

/* 设置文本资源 */
void TextArea::setTypedText(const TypedText& t)
{
	/* 设置文本资源 */
	typedText = t;
	
	/* 根据文本尺寸调整控件尺寸 */
	if (getWidth() == 0 && getHeight() == 0)
	{
		resizeToCurrentText();
	}
	
	/* 重新计算刚好包围文本的边界区域 */
	boundingArea = calculateBoundingArea();
}

/* 根据文本尺寸和旋转方向调整控件尺寸 */
void TextArea::resizeToCurrentText()
{
	if (typedText.hasValidId())
	{
		const uint16_t w = getTextWidth();
		const uint16_t h = getTextHeight();
		if (rotation == TEXT_ROTATE_0 || rotation == TEXT_ROTATE_180)
		{
			setWidthHeight(w, h);
		}
		else
		{
			setWidthHeight(h, w);
		}
	}
}

/* 根据对齐方式、旋转方向和尺寸调整控件尺寸和位置以适应文本 */
void TextArea::resizeToCurrentTextWithAlignment()
{
	if (typedText.hasValidId())
	{
		const Alignment alignment = getAlignment();
		const uint16_t text_width = getTextWidth();
		const uint16_t text_height = getTextHeight();
		
		/* 0/180度 */
		if (rotation == TEXT_ROTATE_0 || rotation == TEXT_ROTATE_180)
		{
			/* 文本不靠左放 */
			if (!((rotation == TEXT_ROTATE_0 && alignment == LEFT) || (rotation == TEXT_ROTATE_180 && alignment == RIGHT)))
			{
				const uint16_t old_width = getWidth();
				const uint16_t old_x = getX();
				if (alignment == CENTER)	//居中
				{
					setX(old_x + (old_width - text_width) / 2);	//调整控件位置
				}
				else	//靠右放
				{
					setX(old_x + (old_width - text_width));	//调整控件位置
				}
			}
			if (rotation == TEXT_ROTATE_180)
			{
				const uint16_t old_height = getHeight();
				const uint16_t old_y = getY();
				setY(old_y + (old_height - text_height));
			}
			
			setWidthHeight(text_width, text_height);
		}
		else
		{
			// 90+left or 270+right places text at the same y coordinate
			if (!((rotation == TEXT_ROTATE_90 && alignment == LEFT) || (rotation == TEXT_ROTATE_270 && alignment == RIGHT)))
			{
				const uint16_t old_height = getHeight();
				const uint16_t old_y = getY();
				if (alignment == CENTER)
				{
					setY(old_y + (old_height - text_width) / 2);
				}
				else
				{
					setY(old_y + (old_height - text_width));
				}
			}
			if (rotation == TEXT_ROTATE_90)
			{
				const uint16_t old_width = getWidth();
				const uint16_t old_x = getX();
				setX(old_x + (old_width - text_height));
			}
			setWidthHeight(text_height, text_width);
		}
	}
}

/* 根据文本高度和旋转方向调整文本尺寸以适应文本 */
void TextArea::resizeHeightToCurrentText()
{
	if (typedText.hasValidId())
	{
		const uint16_t h = getTextHeight();
		if (rotation == TEXT_ROTATE_0 || rotation == TEXT_ROTATE_180)
		{
			setHeight(h);
		}
		else
		{
			setWidth(h);
		}
	}
}

/* 根据文本高度调整和旋转方向文本尺寸和位置以适应文本 */
void TextArea::resizeHeightToCurrentTextWithRotation()
{
	if (typedText.hasValidId())
	{
		const uint16_t h = getTextHeight();
		switch (rotation)
		{
			case TEXT_ROTATE_0:
				setHeight(h);
				break;
			case TEXT_ROTATE_90:
				setX(rect.right() - h);
				setWidth(h);
				break;
			case TEXT_ROTATE_180:
				setY(rect.bottom() - h);
				setHeight(h);
				break;
			case TEXT_ROTATE_270:
				setWidth(h);
				break;
		}
	}
}

/* 计算文本高度:考虑换行 */
int16_t TextArea::calculateTextHeight(const Unicode::UnicodeChar *format, ...) const
{
	if(!typedText.hasValidId())
	{
		return 0;
	}

	va_list pArg;
	va_start(pArg, format);

	/* 获取字体和字体高度 */
	const Font *fontToDraw = typedText.getFont();
	const int16_t textHeight = fontToDraw->getHeight();

	/* 获取给定文本的行数,同时考虑换行 */
	TextProvider textProvider;
	textProvider.initialize(format, pArg, fontToDraw->getGSUBTable(), fontToDraw->getContextualFormsTable());
	const int16_t numLines = LCD::getNumLines(textProvider, wideTextAction, typedText.getTextDirection(), typedText.getFont(), getWidth() - indentation);

	va_end(pArg);
	
	/* 计算高度 */
	return textHeight + linespace > 0 ? numLines * textHeight + (numLines - 1) * linespace : (numLines > 0 ? textHeight : 0);
}

void TextArea::invalidateContent() const
{
    if (alpha == 0 || !typedText.hasValidId() || rect.isEmpty())
    {
        return;
    }
    if (boundingArea.isValid(typedText.getText()))
    {
        Rect boundingRect = boundingArea.getRect();
        invalidateRect(boundingRect);
        return;
    }
    invalidate();
}

/* 计算刚好包围文本的边界区域 */
TextArea::BoundingArea TextArea::calculateBoundingArea() const
{
	if(!typedText.hasValidId())
	{
		return TextArea::BoundingArea(); // Return Invalid BoundingArea
	}

	const Font* fontToDraw = typedText.getFont();
	const Unicode::UnicodeChar* textToDraw = typedText.getText();
	const int16_t fontHeight = fontToDraw->getHeight();
	const int16_t lineHeight = fontHeight + linespace;
	int16_t width = 0;
	uint16_t numberOfLines = 0;

	/* 计算最大行宽 */
	if (wideTextAction == WIDE_TEXT_NONE)
	{
		TextProvider textProvider;
		textProvider.initialize(textToDraw, fontToDraw->getGSUBTable(), fontToDraw->getContextualFormsTable(), getWildcard1(), getWildcard2());
		int16_t widgetRectHeight = (rotation == TEXT_ROTATE_0 || rotation == TEXT_ROTATE_180) ? getHeight() : getWidth();
		do
		{
			const uint16_t lineWidth = LCD::stringWidth(textProvider, *(fontToDraw), 0x7FFF, typedText.getTextDirection());
			width = MAX(width, lineWidth);
			numberOfLines++;
			widgetRectHeight -= lineHeight;
		}while (!textProvider.endOfString() && widgetRectHeight + fontToDraw->getPixelsAboveTop() > 0);
	}
	else
	{
		TextProvider wideTextProvider;
		wideTextProvider.initialize(textToDraw, fontToDraw->getGSUBTable(), fontToDraw->getContextualFormsTable(), getWildcard1(), getWildcard2());

		const int16_t widgetRectWidth = (rotation == TEXT_ROTATE_0 || rotation == TEXT_ROTATE_180) ? getWidth() : getHeight();
		int16_t widgetRectHeight = (rotation == TEXT_ROTATE_0 || rotation == TEXT_ROTATE_180) ? getHeight() : getWidth();
		LCD::WideTextInternalStruct wtis(wideTextProvider, widgetRectWidth - indentation, widgetRectHeight, typedText.getTextDirection(), fontToDraw, linespace, wideTextAction);

		// Iterate through each line, find the longest line width and sum up the total height of the bounding rectangle
		do
		{
				wtis.scanStringLengthForLine();
				const uint16_t lineWidth = wtis.getLineWidth();
				width = MAX(width, lineWidth);
				numberOfLines++;
				widgetRectHeight -= lineHeight;
				// Keep reading until end of string, ellipsis inserted or next line completely invisible.
		} while (wtis.getCurrChar() != 0 && !wtis.ellipsisAtEndOfLine() && widgetRectHeight + fontToDraw->getPixelsAboveTop() > 0);
	}
	
	/* 计算最大高度 */
	int16_t height = (numberOfLines * lineHeight) - linespace;
	height = MAX(height, fontHeight) + fontToDraw->getPixelsBelowBottom();

	/* 边界矩形 */
	Rect boundingRect(0, 0, width, height);

	/* 根据对齐方式调整边界矩形 */
	const int16_t areaWidth = (rotation == TEXT_ROTATE_0 || rotation == TEXT_ROTATE_180) ? getWidth() : getHeight();
	switch (getAlignment())
	{
		default:
		case LEFT:
			boundingRect.x = indentation;
			break;
		
		case CENTER:
			boundingRect.x = ((areaWidth - boundingRect.width) / 2);
			break;
		
		case RIGHT:
			boundingRect.x = areaWidth - (boundingRect.width + indentation);
			break;
	}

	/* 根据字体左右预留像素调整边界矩形 */
	const uint8_t maxPixelsLeft = fontToDraw->getMaxPixelsLeft();
	const uint8_t maxPixelsRight = fontToDraw->getMaxPixelsRight();
	boundingRect.x -= maxPixelsLeft;
	boundingRect.width += (maxPixelsLeft + maxPixelsRight);

	/* 根据文本旋转方向调整边界矩形 */
	switch (rotation)
	{
		case TEXT_ROTATE_0:
			break;
		case TEXT_ROTATE_90:
			boundingRect = Rect(getWidth() - boundingRect.bottom(), boundingRect.x, boundingRect.height, boundingRect.width);
			break;
		case TEXT_ROTATE_180:
			boundingRect = Rect(getWidth() - boundingRect.right(), getHeight() - boundingRect.bottom(), boundingRect.width, boundingRect.height);
			break;
		case TEXT_ROTATE_270:
			boundingRect = Rect(boundingRect.y, getHeight() - boundingRect.right(), boundingRect.height, boundingRect.width);
			break;
	}

	return TextArea::BoundingArea(boundingRect, typedText.getText());
}

}

控件组​

文本区域位于TouchGFX Designer中的Miscellaneous控件组中。

TouchGFX Designer中的文本区域

属性​

TouchGFX Designer中文本区域的属性。

属性组属性说明
名称控件的名称。 名称是TouchGFX Designer和代码中使用的唯一标识符
位置XY指定控件左上角相对于其父的位置。

WH指定控件的宽度和高度。

自动调整大小指定是否根据文本输入自动设置控件的大小。

锁定指定控件是否应锁定为其当前的X、Y、W和H。
如果锁定控件,还会禁止通过屏幕与控件进行交互。

可见指定控件的可见性。
如果将控件标记为不可见,还会禁止通过屏幕与控件进行交互。
文本ID指定使用的文本。 如果控件使用自动生成的文本,ID将显示“自动生成”。.

翻译指定要显示的文本内容。

字体排印指定文本的格式。

对齐指定文本的水平对齐方式。

最多可以为动态文本输入创建两个通配符,表示为‘<tag>’,其中‘tag’可以是任意字符串。 如需详细了解关于文本配置的信息,请参阅“文本与字体”一节。
外观颜色指定所显示文本的颜色。

Alpha指定控件的透明度。
控件Alpha值的范围是0到255。 0表示完全透明,255表示不透明。

行距指定行之间的间距。

文本旋转设置文本的旋转角度。

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

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

相关文章

软件设计不是CRUD(16):低耦合模块设计理论——行为抽象与设计模式(下)

(接上文《软件设计不是CRUD(15):低耦合模块设计理论——行为抽象与设计模式(中)》) 3.2.4、之前的业务逻辑需要关注后续逻辑的执行成败,并调整自身执行的情况 这个场景在之前场景的基础上增加了新的控制要求,具体来说就是之前已经完成的控制逻辑执行,需要在后续控制…

Vue基础配置、组件通信

基础配置 Vue框架已经集成了webpack配置 小注意点 vbase 快速生成vue模板 组件名必须是多词格式(驼峰模式) 具体三种写法: ①小驼峰:abcDef.vue ②大驼峰&#xff1a;AbcDef.vue ③中横线&#xff1a;abc-def.vue 假如文件名不符合多次格式的补救办法&#xff1a; 导出重命名…

MySQL数据库MHA高可用集群

前言 MySQL 数据库 MHA&#xff08;Master High Availability&#xff09;高可用集群是一种用于提高 MySQL 数据库可用性的解决方案。它通过自动故障切换和监控来确保数据库系统在主服务器发生故障时能够快速切换到备用服务器&#xff1b;在 MHA 高可用集群中&#xff0c;Mast…

线程与同步

目录 一&#xff0c;线程概念 1&#xff0c;什么是线程 2&#xff0c;Linux 下的线程 3&#xff0c;POSIX 线程库 二&#xff0c;线程同步 1&#xff0c;数据不一致问题 2&#xff0c;如何解决这类问题 3&#xff0c;死锁 三&#xff0c;线程同步的运用 1&#xff0c…

第十四届蓝桥杯省赛C++ B组所有题目以及题解(C++)【编程题均通过100%测试数据】

第一题《日期统计》【枚举】 【问题描述】 小蓝现在有一个长度为100的数组&#xff0c;数组中的每个元素的值都在0到9的范围之内。数组中的元素从左至右如下所示&#xff1a; 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 …

【Go】五、流程控制

文章目录 1、if2、switch3、for4、for range5、break6、continue7、goto8、return 1、if 条件表达式左右的()是建议省略的if后面一定要有空格&#xff0c;和条件表达式分隔开来{ }一定不能省略if后面可以并列的加入变量的定义 if count : 20;count < 30 {fmt.Println(&quo…

剑指Offer题目笔记22(快速排序)

快速排序定义&#xff1a; ​ 快速排序的基本思想是分治法&#xff0c;排序过程如下&#xff1a;在输入数组中随机选取一个元素作为中间值&#xff08;pivot&#xff09;&#xff0c;然后对数组进行分区&#xff08;partition&#xff09;&#xff0c;使所有比中间值小的数据移…

DC电源模块的分类及特点介绍

BOSHIDA DC电源模块的分类及特点介绍 DC电源模块是一种将交流电转换为直流电的设备&#xff0c;广泛应用于各种电子设备中。根据其特点和功能&#xff0c;DC电源模块可以分为线性稳压模块和开关稳压模块两种。本文将详细介绍这两种DC电源模块的分类和特点&#xff0c;以便读者…

[C++初阶] 爱上C++ : 与C++的第一次约会

&#x1f525;个人主页&#xff1a;guoguoqiang &#x1f525;专栏&#xff1a;我与C的爱恋 本篇内容带大家浅浅的了解一下C中的命名空间。 在c中&#xff0c;名称&#xff08;name&#xff09;可以是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大&#xff0c;名称…

京东云服务器价格_云主机价格查询系统_2024年京东云优惠活动

2024年京东云服务器优惠价格表&#xff0c;轻量云主机优惠价格5.8元1个月、轻量云主机2C2G3M价格50元一年、196元三年&#xff0c;2C4G5M轻量云主机165元一年&#xff0c;4核8G5M云主机880元一年&#xff0c;游戏联机服务器4C16G配置26元1个月、4C32G价格65元1个月、8核32G费用…

爬虫学习(爬取音乐)

import re import requestsurl "http://www.yy8844.cn/ting/numes/sussoc.shtml" response requests.get(url) response.encoding "gbk" # print(r.text) #第一步&#xff0c;访问网页获取MusicID p re.compile(r"MusicId(.*?);",re.S) prin…

VBA技术资料MF135:多值匹配查找

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

Hyper-V 虚拟机设置静态 IP 和外网访问

文章目录 环境说明1 问题简介2 解决过程 环境说明 宿主机操作系统&#xff1a;Windows 11 专业版漏洞复现操作系&#xff1a;debian-live-12.5.0-amd64-standard 1 问题简介 在 Windows 上用自带的 Hyper-V 虚拟机管理应用创建了一个 Debian 12 虚拟机&#xff0c;配置静态 IP…

Linux vim用法

在命令模式下&#xff0c;点i 进入输入模式 输入模式下&#xff1a;通过箭头可以实现左右上下移动 o是从新起下一行开始写 O是新起上一行开始写 $是到此行的末尾 0是到此行的开头 gg是到第一行 yy是复制此行&#xff0c;p是粘贴 dd是删除此行 u是撤销 Ctrl r是反向撤…

启信宝商业大数据助力全国经济普查

近日&#xff0c;合合信息旗下启信宝收到中国青年创业就业基金会感谢信&#xff0c;对启信宝协同助力全国经济普查和服务青年创业就业研究表达感谢。 第五次全国经济普查是新时代新征程上一次重大国情国力调查&#xff0c;是对国民经济“全面体检”和“集中盘点”&#xff0c;…

若依菜单名称过长显示不全怎么办?

菜单名称太长的话超出宽度部分会显示...,我们可以自己调整一下菜单的宽度或者设置一个title,这样鼠标移动上去显示完整的菜单名称。 目录 1、在layout\components\Sidebar\SidebarItem.vue文件设置:title 2、在layout\components\Sidebar\Item.

简单的LAMP部署

目录 一、准备环境 二、安装apache组件 三、安装mysql组件 四、安装php组件 五、浏览器访问 一、准备环境 iptables -F #清空防火墙规则 systemctl stop firewalld #关闭防火墙 setenforce 0 …

bugku-web-eval

页面源码 <code><span style"color: #000000"> <span style"color: #0000BB"><?php <br /> </span><span style"color: #007700">include </span><span style"color: #DD0000"&…

Facebook轮播广告是什么?投放过程中有哪些需要注意的吗?

轮播广告是Facebook广告形式中的一种&#xff0c;可以把3—5个广告合并到一个可滚动的广告单元中。轮播广告会出现在新鲜事即News Feed中&#xff0c;是独立站卖家常用的一种广告形式 为什么选择轮播广告&#xff1f; 转化率更高&#xff1a;相较于单图广告&#xff0c;轮播广…

个人简历主页搭建系列-04:网站初搭建

准备工作差不多了&#xff0c;该开始搭建网站了&#xff01; 这次我们先把网站搭建部署起来&#xff0c;关于后续主题内容等更换留到后续。 创建源码文件夹 首先通过 hexo 创建本地源码文件夹。因为最终部署的 github 仓库格式为 websiteName.github.io&#xff08;websiteN…