Qt事件系统 day7

news2024/7/4 5:48:59

Qt事件系统 day7

事件系统

  • 在Qt中,事件是派生自抽象QEvent类的对象,它表示应用程序内发生的事情或应用程序需要知道的外部活动的结果。事件可以由QObject子类的任何实例接收和处理,但它们与小部件尤其相关。
  • Qt程序需要在main()函数创建一个QApplication对象,然后调用它的exec()函数。这个函数就是开始Qt的事件循环。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件,当事件发生时,Qt将创建一个事件对象
  • 当事件发生时,Qt通过构造适当的QEvent子类的实例来创建一个事件对象来表示它,并通过调用它的event()函数将它交付给QObject的一个特定实例(或它的一个子类)。
  • 这个函数event()不处理事件本身;根据交付的事件类型,它为该特定类型的事件调用事件处理程序,并根据事件是被接受还是被忽略发送响应。
  • 一些事件,如QMouseEvent和QKeyEvent,来自窗口系统;还有一些,比如QTimerEvent,来自其他来源;有些来自应用程序本身。

事件处理

  • 传递事件的通常方式是调用虚函数
    在这里插入图片描述
  • 自定义处理了按钮控件左键单击,想要让父类也能够处理左键消息,可以把父类的mousePressEvent放在最后调用(不放在else中)
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
class Button :public QPushButton
{
public:
	Button(QWidget* parent = nullptr) :QPushButton(parent)
	{

	}
protected:
	//重写了父类的虚函数,也就是不再使用父类的实现,由自己来实现
	//但是按钮的点击信号,是在mousePressEvent函数里面触发的
	void mousePressEvent(QMouseEvent* ev) override
	{
		if (ev->button() == Qt::MouseButton::LeftButton)
		{
			qDebug() << "按下小瓜";
		}
		//所以写完实现后,剩下的要交给父类处理
		QPushButton::mousePressEvent(ev);
	}
};
class Widget :public QWidget
{
public:
	Widget(QWidget* parent = nullptr) :QWidget(parent)
	{
		auto btn = new Button(this);
		btn->setText("小瓜");

		connect(btn, &Button::clicked,this, []()
			{
				qDebug() << "小瓜瓜";
			}
		);
	}
	//处理鼠标点击事件,重写虚函数即可
	void mousePressEvent(QMouseEvent* ev) override
	{
		//判断那个键按下
		if (ev->button() == Qt::MouseButton::LeftButton)
		{
			//pos是程序的客户区坐标,globalPos是基于整个屏幕所在的坐标位
			qDebug() << "leftButton Press" << ev->pos() << ev->globalPos();
		}
	}

};

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);
	Widget w;
	w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));
	w.show();
	
	return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

鼠标事件

  • 鼠标按下
void CustomButton::mousePressEvent(QMouseEvent* ev)override
{
	//获取鼠标按键 类型为枚举:Qt::MouseButton::
	qDebug() << ev->button();

	//如果同时有多个鼠标按键按下,需要判断左键是否按下
	qDebug() << (ev->buttons() & Qt::MouseButton::LeftButton);

	//获取鼠标坐标 position()返回浮点坐标,可以使用pos()获取整型坐标
	qDebug() << ev->position();			//鼠标在本控件上的坐标
	qDebug() << ev->scenePosition();		//鼠标在本控件所在的窗口位置
	qDebug() << ev->globalPosition();	//鼠标相对于屏幕的坐标

	//将其他按键传递给基类处理
	QPushButton::mousePressEvent(ev);
}
  • 鼠标释放
void CustomButton::mouseReleaseEvent(QMouseEvent*ev)override
{
	QPushButton::mouseReleaseEvent(ev);
}
  • 鼠标双击
void CustomButton::mouseDoubleClickEvent(QMouseEvent*ev)override
{
	qDebug() << "小瓜";
}
  • 鼠标移动
  • 如果关闭了鼠标跟踪,则只有在移动鼠标时按下鼠标按钮时才会发生鼠标移动事件。如果打开了鼠标跟踪,即使没有按下鼠标按钮,也会发生鼠标移动事件。按钮是自动追踪鼠标的,但是QWidget是不会的,如果要给QWidget的子类重写鼠标移动,需要使用 void setMouseTracking(bool enable)启用鼠标追踪。
void CustomButton::mouseMoveEvent(QMouseEvent* ev)override
{
	qDebug() << "鼠标移动的坐标位" << ev->pos();
}
  • 鼠标滚轮
  • 返回轮子旋转的相对量,单位为八分之一度。正值表示转轮向前旋转,远离用户;负值表示转轮向后向用户旋转。angleDelta().y()提供自上一个事件以来旋转普通垂直鼠标滚轮的角度。如果鼠标有水平滚轮,angleDelta().x()提供水平鼠标滚轮旋转的角度,否则就是0。有些鼠标允许用户倾斜滚轮来进行水平滚动,有些触摸板支持水平滚动手势;它也会出现在angleDelta().x()中。
  • 大多数鼠标类型的工作步长为15度,在这种情况下,delta值是120的倍数;即120单位* 1/8 = 15度。
  • 然而,有些鼠标的滚轮分辨率更高,发送的delta值小于120单位(小于15度)。为了支持这种可能性,可以累计添加来自事件的增量值,直到达到120的值,然后滚动小部件,或者可以部分滚动小部件以响应每个轮事件
void CustomButton::wheelEvent(QWheelEvent* ev)override
{
	//获取滚轮滚动方向
	QPoint numDegrees = ev->angleDelta();
	qDebug() <<"水平:" << numDegrees.x()/8 <<"垂直:" << numDegrees.y()/8;
}
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
class Button :public QPushButton
{
public:
	Button(QWidget* parent = nullptr) :QPushButton(parent)
	{

	}
protected:
	//重写了父类的虚函数,也就是不再使用父类的实现,由自己来实现
	//但是按钮的点击信号,是在mousePressEvent函数里面触发的
	void mousePressEvent(QMouseEvent* ev) override
	{
		if (ev->button() == Qt::MouseButton::LeftButton)
		{
			qDebug() << "按下小瓜";
		}
		//所以写完实现后,剩下的要交给父类处理
		QPushButton::mousePressEvent(ev);
	}
};
class Widget :public QWidget
{
public:
	Widget(QWidget* parent = nullptr) :QWidget(parent)
	{
		auto btn = new Button(this);
		btn->setText("小瓜");

		connect(btn, &Button::clicked,this, []()
			{
				qDebug() << "小瓜瓜";
			}
		);

		//设置鼠标追踪,不需要的情况就不要用,会降低效率
		//setMouseTracking(true);
	}
	//处理鼠标点击事件,重写虚函数即可
	void mousePressEvent(QMouseEvent* ev) override
	{
		//判断那个键按下
		if (ev->button() == Qt::MouseButton::LeftButton)
		{
			//pos是程序的客户区坐标,globalPos是基于整个屏幕所在的坐标位
			qDebug() << "leftButton Press" << ev->pos() << ev->globalPos();
			
			isPress = true;
		}

	}

	//鼠标放开
	void mouseReleaseEvent(QMouseEvent* ev) override
	{
		if (ev->button() == Qt::MouseButton::LeftButton)
		{
			isPress = false;
		}
	}

	//移动鼠标
	void mouseMoveEvent(QMouseEvent* ev) override
	{
		//鼠标左键按下,并且移动了鼠标,实现这个要开启鼠标追踪
		if (isPress)
		{
			qDebug() << "左键按下,也移动的鼠标";
		}
		//buttons判断鼠标按下后还做了别的事情
		if(ev->buttons() & Qt::MouseButton::RightButton)
		{
			qDebug() << "移动了鼠标并且按了右击";
		}
		
	}

	//双击
	void mouseDoubleClickEvent(QMouseEvent* ev) override
	{
		qDebug() << "双击";
	}

	//滚轮
	void wheelEvent(QWheelEvent* ev) override
	{
		//判断滚轮的方向
		qDebug() << ev->angleDelta().y() << ev->angleDelta().x();
	}
private:
	bool isPress = false;

};

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);
	Widget w;
	w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));
	w.show();
	
	return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

按键事件

在这里插入图片描述

在这里插入图片描述

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>

class Widget :public QWidget
{
public:
	Widget(QWidget* parent = nullptr) :QWidget(parent)
	{
		//遍历Qt中的所有快捷键
		for (size_t i = 0; i < 70; i++)
		{
			qDebug() << i << "-----" << QKeySequence::StandardKey(i) << "------"
				<< QKeySequence::keyBindings(QKeySequence::StandardKey(i));
		}
	}

	//按键事件
	void keyPressEvent(QKeyEvent* ev) override
	{
		//当前是什么键按下
		qDebug() << Qt::Key(ev->key());
		//描述键 ctrl alt shift键等等
		//ctrl+A
		if (ev->modifiers() & Qt::KeyboardModifier::ControlModifier && ev->key() == Qt::Key_A)
		{
			qDebug() << "全选";
		}
		//matches:匹配
		if (ev->matches(QKeySequence::StandardKey::Save))
		{
			qDebug() << "保存";
		}
	}

	//按键放开事件
	void keyReleaseEvent(QKeyEvent* ev) override
	{

	}
private:
};

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);
	Widget w;
	w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));
	w.show();
	
	return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

窗口关闭事件、大小改变、其他事件处理

  • 窗口关闭
    • 当Qt从窗口系统接收到一个顶级小部件的窗口关闭请求时,将用给定的事件调用此事件处理程序。
    • 默认情况下,接受事件并关闭小部件。您可以重新实现此函数,以更改小部件响应窗口关闭请求的方式。例如,您可以通过在所有事件上调用ignore()来防止窗口关闭。
    • 主窗口应用程序通常使用该函数的重新实现来检查用户的工作是否已保存,并在关闭前请求权限。
void Widget::closeEvent(QCloseEvent* ev)override
{
    auto ret = QMessageBox::question(this, "温馨提示", "你有未保存的操作,是否保存并关闭?");
    if (ret == QMessageBox::StandardButton::Yes)
    {
        //保存并关闭
        ev->accept();
        //ev->setAccepted(true);
    }
    else
    {
        //不保存也不关闭
        ev->ignore();
        //ev->setAccepted(false);
    }
}
  • 窗口隐藏、显示
    • 除隐藏和显示窗口外,窗口最小化会发送窗口隐藏事件,正常显示会发送窗口显示事件。
void Widget::showEvent(QShowEvent* ev)override
{
    qInfo() << "我显示啦~";
}
void Widget::hideEvent(QHideEvent* ev)override
{
    qInfo() << "我隐藏啦~";
}

  • 窗口移动
void Widget::moveEvent(QMoveEvent* ev)override
{
    qInfo() << "Widget moved" << "oldPos" << ev->oldPos() << "newPos" << ev->pos();
}
  • 窗口大小改变
void  Widget::resizeEvent(QResizeEvent* ev)override
{
    qInfo() << "Widget SizeChanged" << "oldSize" << ev->oldSize() << "newSize" << ev->size();
}
  • 程序状态改变
    • 如果需要检测程序中,某些东西是否发生了改变,可以通过void QWidget::changeEvent(QEvent *event)来检测。
  • 以下是常用事件
    • QEvent::FontChange
    • QEvent::WindowTitleChange
    • QEvent::IconTextChange
    • QEvent::ModifiedChange
    • QEvent::MouseTrackingChange
    • QEvent::WindowStateChange
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
class Widget :public QWidget
{
	Q_OBJECT
public:
	Widget(QWidget* parent = nullptr) :QWidget(parent)
		, btn(new QPushButton("更改标题", this))
	{
		resize(400, 400);
		btn->setFixedSize(100, 100);
		connect(btn, &QPushButton::clicked, this, [=]()
			{
				setWindowTitle("小瓜瓜");
			}
		);
	}

	//窗口关闭事件
	void closeEvent(QCloseEvent* ev) override
	{
		auto ret = QMessageBox::question(this, "关闭窗口", "是否保存");
		if (ret == QMessageBox::StandardButton::Yes)
		{
			//接收事件
			ev->accept();
		}
		else
		{
			//忽略事件
			ev->ignore();
		}
	}
	//当窗口大小改变的时候,会调用
	void  resizeEvent(QResizeEvent* ev) override
	{
		//这样窗口大小改变的时候,按钮也会跟着变
		btn->move(ev->size().width() - btn->width(), 0);
	}

	void changeEvent(QEvent* ev) override
	{
		switch (ev->type())
		{
		case QEvent::Type::WindowTitleChange:qDebug() << "改变标题" << this->windowTitle(); break;
		}
	}
private:
	QPushButton* btn{};
};

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);
	Widget w;
	w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));
	w.show();
	
	return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

定时器

  • 有两种定时器
  • 定时器:周期性处理,因为在Qt中不能写死循环,不然会导致主程序的阻塞
  • 第一种是QTimer
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
#include <QTimer>
class Widget :public QWidget
{
	Q_OBJECT
public:
	Widget(QWidget* parent = nullptr) :QWidget(parent) 
	{
		//两种定时器
		//1.QTimer
		auto timer = new QTimer(this);

		//最简单的调用,使用lambda表达式
		/*timer->callOnTimeout([]()
			{
				qDebug() << "upData";
			}
		);*/

		timer->callOnTimeout(this, &Widget::game_upData);

		//发送信号到槽函数
		connect(timer, &QTimer::timeout, this, &Widget::game_upData);

		//开启定时器,60帧速度
		timer->start(1000/60);

		//QTimer的静态成员,这个示例在1000毫秒后,只会触发一次
		QTimer::singleShot(1000, []()
			{
				qDebug() << "只触发一次";
			}
		);
	}


	void game_upData()
	{
		qDebug() << __FUNCTION__;
	}
private:
	
};

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);
	Widget w;
	w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));
	w.show();
	
	return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述
  • 第二种定时器事件,只要在QOBject的子类里面,就可以重写定时器事件
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
#include <QTimer>
class Widget :public QWidget
{
	Q_OBJECT
public:
	Widget(QWidget* parent = nullptr) :QWidget(parent)
	{
		//开启定时器
		timer_idOne = startTimer(500);
		timer_idTow = startTimer(200);
	}

	//定时器事件
	void timerEvent(QTimerEvent* ev) override
	{
		static int i = 0;
		//当i为6的时候杀死定时器
		if (i == 6)
		{
			killTimer(timer_idOne);
			killTimer(timer_idTow);

			//killTimer(ev->timerId());
		}
		if (ev->timerId() == timer_idOne)
		{
			qDebug() << timer_idOne;
		}
		else if (ev->timerId() == timer_idTow)
		{
			qDebug() << timer_idTow;
		}
		i++;
	}

private:
	//timer的id接收变量
	int timer_idOne;
	int timer_idTow;
};

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);
	Widget w;
	w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));
	w.show();
	
	return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

自定义事件的发送与处理

事件分发函数

  • 传递事件通常方式是调用虚函数,如果在虚函实现中不执行必要的工作,则可能需要调用基类的实现
  • 如果希望替换基类的事件处理函数,则必须自己实现所有的内容,实现自己所需的功能后,可以调用基类来获得不想处理的任何情况的默认行为
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
#include <QTimer>
class Widget :public QWidget
{
	Q_OBJECT
public:
	Widget(QWidget* parent = nullptr) :QWidget(parent)
	{
	
	}
	//所有的事件处理函数都是从event()事件派发函数调用的
	bool event(QEvent* ev) override
	{
		switch (ev->type())
		{
			//实现自己需要的事件操作
			case QEvent::MouseButtonPress:mousePressEvent(dynamic_cast<QMouseEvent*>(ev)); break;
			default:
				break;
		}
		//最后交给父类去处理
		return QWidget::event(ev);
	}
	
	void mousePressEvent(QMouseEvent* ev) override
	{
		qDebug() << ev->button();
	}
private:

};

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);
	Widget w;
	w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));
	w.show();
	
	return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述
发送事件
  • 自定义事件创建与发送,通过构造合适的事件对象并进行使用
  • sendEvent():立即处理事件。当它返回时,事件过滤器或对象本身已经处理了该事件,对于许多事件类。都有一个名为isAccept()的函数,它会告诉事件是被最后一个调用的处理程序接受还是拒绝
  • postEvent():将事件发送到队列中,以便进行分派。它会分发所有发布的事件。
  • 用户自定义的类型必须要在这个区间里
    在这里插入图片描述
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QMessageBox>
#include <QTimer>
//自定义事件
class CustomEvent :public QEvent
{
public:
	enum Type { custom = QEvent::User };
	CustomEvent(const QString& data) :QEvent(static_cast<QEvent::Type>(custom))
		,m_data(data)
	{

	}
	//析构函数
	~CustomEvent()
	{
		qDebug() << __FUNCTION__;
	}
	//提供接口
	QString data() const
	{
		return m_data;
	}
protected:
	QString m_data;
};
class Widget :public QWidget
{
	Q_OBJECT
public:
	Widget(QWidget* parent = nullptr) :QWidget(parent)
	{
	
	}
	void mousePressEvent(QMouseEvent* ev) override
	{
		if (ev->button() == Qt::RightButton)
		{
			//向指定的对象发送事件
			//1.sendEvent 发送栈区的事件,直到事件处理或完成之后,才会返回(表明sendEvent函数是阻塞的)
			//如果申请内存放在堆区就不会自动释放,需要自己所手动释放
			//CustomEvent ev("小瓜 sendEvetn customEvent");
			//QApplication::sendEvent(this, &ev);

			//2.postEvent 只能发送堆区的对象。一旦发送,直接返回,不需要等事件处理完成,一旦事件处理完成会自动释放
			CustomEvent* ev = new CustomEvent("小瓜瓜");
			QApplication::postEvent(this, ev);
		}
	}
	//处理自定义事件函数
	void customEvent(QEvent* ev) override
	{
		if (ev->type() == CustomEvent::custom)
		{
			auto cev = dynamic_cast<CustomEvent*>(ev);
			if (cev)
			{
				qDebug() <<  cev->data();
			}
		}
	}
private:
};

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);
	Widget w;
	w.setWindowIcon(QIcon(":/Resource/tubiao.ico"));
	w.show();
	
	return a.exec();
}
#include "main.moc"
  • 运行结果
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【iOS】Mac M1安装iPhone及iPad的app时设置问题

【iOS】Mac M1安装iPhone及iPad的app时设置问题 简介一&#xff0c;设置问题二&#xff0c;适配问题 简介 由于 苹果M1芯片的Mac可用安装iPhone以及iPad应用&#xff0c;因为开发者并没有适配Mac&#xff0c;因此产生了很多奇怪问题&#xff0c;这里总结归纳Mac M1安装iPhone和…

C++之委托构造函数实例(二百四十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

学信息系统项目管理师第4版系列26_项目绩效域(下)

1. 项目工作绩效域 1.1. 涉及项目工作相关的活动和职能 1.2. 预期目标 1.2.1. 高效且有效的项目绩效 1.2.2. 适合项目和环境的项目过程 1.2.3. 干系人适当的沟通和参与 1.2.4. 对实物资源进行了有效管理 1.2.5. 对采购进行了有效管理 1.2.6. 有效处理了变更 1.2.7. 通…

第八章:网络设备文件管理)

网络设备文件管理 一、网络设备的文件系统1. 网络设备的存储方式2. 网络设备的操作 二、文件管理1. 配置文件的操作2. 配置文件的显示与维护![ ](https://img-blog.csdnimg.cn/a4f36f4e8f50422eb76be4ea7794bad9.png) 三、网络连通测试四、系统调试 一、网络设备的文件系统 1. …

2023年09月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 Python编程&#xff08;1~6级&#xff09;全部真题・点这里 第1题&#xff1a;生日相同 在一个有180人的大班级中&#xff0c;存在两个人生日相同的概率非常大&#xff0c;现给出每个学生的名字&#xff0c;出生月日。试…

idea 启动出现 Failed to create JVM JVM Path

错误 idea 启动出现如下图情况 Error launching IDEA If you already a 64-bit JDK installed, define a JAVA_HOME variable in Computer > System Properties> System Settings > Environment Vanables. Failed to create JVM. JVM Path: D:\Program Files\JetB…

Redis微服务架构

Redis微服务架构 缓存设计 缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c;缓存层和存储层都不会命中&#xff0c;通常出于容错的考虑&#xff0c;如果从存储层查不到数据则不写入缓层。 缓存穿透将导致不存在的数据每次请求都要到存储层去查询&#xff0c;失去…

真正牛的项目经理,都做到了这几点

大家好&#xff0c;我是老原。 不管你是在大厂还是小厂&#xff0c;都可以看到这么一群人&#xff0c;他们具备&#xff1a;优秀的产品规划、持续的商务拓展、准时交付项目/产品。 然后大部分人是&#xff1a;一般的产品规划、眼睁睁看着客户流失、项目/产品交付不断推迟。 …

private key ssh连接服务器

这里用到的软件是PuTTY。 https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html 保存本地rsa文件后&#xff0c;打开软件PuTTYgen&#xff0c;点击Load导入文件&#xff0c;输入Key passphrase即密码&#xff0c;保存至本地。 随后在PuTTY配置ssh的用户名 来Cred…

网络报修心得

文章目录 JNU 网络牛牛有线锐捷跳出不允许开启VPN 为他人代理 JNU 网络牛牛 有线 锐捷跳出不允许开启VPN 为他人代理 问题表现&#xff1a;打游戏开启加速器后&#xff0c;频繁冒出提示&#xff0c;然后频繁下线&#xff0c;但是电脑无线使用正常问题原因&#xff1a;一般是加…

Apache Doris 在小鹅通的应用实践

峰会官网已上线&#xff0c;最新议程请关注&#xff1a;doris-summit.org.cn 点击报名 先到先得 本文导读&#xff1a; 随着网络直播规模的不断扩大&#xff0c;在线知识服务在直播行业中迎来了广阔的发展机遇。小鹅通作为一家以用户服务为核心的技术服务商&#xff0c;通过多平…

【Java学习之道】GUI开发的基本概念

引言 在这一章&#xff0c;我们将一起走进Java的图形用户界面&#xff08;GUI&#xff09;开发的世界。在你阅读完这篇文章后&#xff0c;你将能够了解什么是GUI&#xff0c;以及如何使用Java进行GUI的开发。 一、什么是GUI 首先&#xff0c;让我们来解答一个许多初学者都会…

互联网Java工程师面试题·Java 并发编程篇·第五弹

目录 52、什么是线程池&#xff1f; 为什么要使用它&#xff1f; 53、怎么检测一个线程是否拥有锁&#xff1f; 54、你如何在 Java 中获取线程堆栈&#xff1f; 55、JVM 中哪个参数是用来控制线程的栈堆栈小的? 56、Thread 类中的 yield 方法有什么作用&#xff1f; 57、…

C#开发的OpenRA游戏之金钱系统(1)

C#开发的OpenRA游戏之金钱系统(1) 设计一个游戏,肯定要有一个唯一的资源,用这个资源来管理整个游戏的进度,以及相互争夺的焦点。在OpenRA里,就是使用矿产资源。所以在地图上分布几个矿场,玩家就需要相互争夺矿场,谁开采多谁就更有钱,谁有钱了就可以升级更好的科技,以…

新版WordPress插件短视频去水印小程序源码

最新版去水印小程序源码&#xff0c;本版本全开源&#xff0c;是WordPress插件 上传到Wordpress 安装插件 启动之后 绑定自己的小程序id wordpress可以在宝塔一键部署 也可以用我的这个 搭建前我们需要一下东西&#xff1a; 第一个&#xff1a;一台服务器&#xff08;国内外都可…

深度学习中的激活函数

给定一个线性变换可以把x的值映射到一条直线上&#xff0c;如下图 输出结果就是y1w1xb1 如果y1经过一个线性变换得到一个y2&#xff0c;那么x和y2的关系是什么&#xff1f; 答案&#xff0c;毫无疑问是一条直线&#xff0c;不管如何的线性变换&#xff0c;依旧是一个线性的问…

Android平台轻量级RTSP服务模块编码前后数据源对接探究

技术背景 好多开发者可能有个疑惑&#xff0c;什么时候轻量级RTSP服务&#xff1f;为什么需要有轻量级RTSP服务模块&#xff1f;实际上&#xff0c;轻量级RTSP服务解决的核心痛点是不需要用户额外部署RTSP或者RTMP流媒体服务&#xff0c;实现本地的音视频&#xff08;如摄像头…

openguass数据库描述指令集合(等保)

1、查看数据库是否配置了密码复杂度&#xff0c;密码最小使用长度是否大于8位&#xff0c;密码复杂度的要求是否包含3类不同字符。 A&#xff1a;数据库密码&#xff1a;K~3m5Kzbjf_zDr!^2K)#。满足要求。 2、数据库密码最大使用期限配置是否小于90天。 A&#xff1a;passwor…

把字符串转换成整数[考虑溢出]

把字符串转换成整数 1.不考虑溢出也能过[牛客测试不全面] class Solution { public:int StrToInt(string str) {int answer 0; int isplus 1;for (char& ch : str) { if (ch )isplus 1;else if (ch -)isplus - 1;else{if (ch < 1 || ch > 9)return 0;elsean…

设计模式_命令模式

命令模式 介绍 定义案例问题堆积在哪里解决办法 行为形设计模式 就是把 “发布命令 执行命令”细化为多个角色 每个角色又能继续细化 发布命令 1 打印1-9 a 打印A-G 如果有更多的命令 命令处理方式更加多样性 更复杂 处理命令的顺序拆分角色&#xff1a;降低耦合度 命令类&am…