Qt Event事件系统小探2
目录
事件过滤器
来看一个例子
拖放事件和拖放操作
Qt官方文档给出的说明
拖放
拖放类
配置
拖动
放置
覆盖建议的操作
子类化复杂窗口小部件
拖放操作
添加新的拖放类型
放置操作
放置矩形
剪贴板
其他函数的介绍
事件过滤器
我们知道,有的时候想要重新定义一个控件的事件行为,就需要对这个类进行重载,然而当我们的类达到了成百上千,如果我们只是想要传递事件做出响应,好像啥都重载未免太过抽象了。所以,这里就有一个办法,那就是eventFilter函数来做这个事情
这种技术适合于一个对象需要查看并可能拦截传递给另一个对象的事件这个场景。例如,对话框通常需要过滤某些小部件的按键;例如,修改回车键处理。
QObject::installEventFilter() 函数通过设置事件过滤器来实现这一点,从而使指定的过滤器对象在其 QObject::eventFilter() 函数中接收目标对象的事件。事件过滤器可以在目标对象之前处理事件,从而允许其根据需要检查和丢弃事件。可以使用 QObject::removeEventFilter() 函数删除现有的事件过滤器。
当调用过滤器对象的 eventFilter() 实现时,它可以接受或拒绝事件,并允许或拒绝进一步处理事件。如果所有事件过滤器都允许进一步处理事件(通过每个都返回 false),则事件将发送到目标对象本身。如果其中一个停止处理(通过返回 true),则目标和任何后续事件过滤器根本看不到该事件。
bool FilterObject::eventFilter(QObject *object, QEvent *event) {if (object == target && event->type() == QEvent::KeyPress) {QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);if (keyEvent->key() == Qt::Key_Tab) {// 特殊 Tab 处理return true;} elsereturn false;}return false; }
上面的代码显示了另一种拦截发送到特定目标窗口小部件的 Tab 键按下事件的方法。在这种情况下,过滤器处理相关事件并返回 true 以阻止进一步处理它们。所有其他事件都将被忽略,过滤器返回 false 以允许它们通过安装在其上的任何其他事件过滤器发送到目标窗口小部件。
还可以通过在 QApplication 或 QCoreApplication 对象上安装事件过滤器来过滤整个应用程序的所有事件。此类全局事件过滤器在对象特定过滤器之前调用。这非常强大,但它也会减慢整个应用程序中每个事件的传递速度
来看一个例子
我们来试试使用EventFilter来表达事件改变了控件的行为,事情很简单。在UI界面上部署好一个按钮控件和一个Label控件之后,直接写入:
#include "MainWindow.h" #include "ui_MainWindow.h" MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);ui->pushButton->installEventFilter(this);ui->label->installEventFilter(this); } bool MainWindow::eventFilter(QObject *watched, QEvent *event) {if (watched == ui->pushButton) {if (event->type() == QEvent::Enter) {ui->pushButton->setText("Mouse entered");} else if (event->type() == QEvent::Leave) {ui->pushButton->setText("Mouse leaved");} else if (event->type() == QEvent::MouseButtonPress) {ui->pushButton->setText("Mouse pressed");} else if (event->type() == QEvent::MouseButtonDblClick) {ui->pushButton->setText("Mouse double clicked");}} else if (watched == ui->label) {if (event->type() == QEvent::Enter) {ui->label->setText("Mouse entered");} else if (event->type() == QEvent::Leave) {ui->label->setText("Mouse left");}} return QMainWindow::eventFilter(watched, event); } MainWindow::~MainWindow() {delete ui; }
这个代码并不难懂,实际上就是对我们感兴趣的事件进行重载即可。值得注意的是:最后不能直接写返回true的是简单的——我们没有处理完所有控件的事件!必须调用默认的函数处理余下的行为!
拖放事件和拖放操作
Qt官方文档给出的说明
拖放
拖放提供了一种简单的可视化机制,用户可使用它在应用程序之间和内部传输信息。拖放的功能类似于剪贴板的剪切和粘贴机制。Qt 的许多控件也支持拖放操作,例如项目视图和图形视图框架,以及 Qt Widgets 和 Qt Quick 的编辑控件。
拖放类
类/事件 | 描述 |
---|---|
QDrag | 支持基于 MIME 的拖放数据传输 |
QDragEnterEvent | 当拖放操作进入窗口小部件时,向窗口小部件发送事件 |
QDragLeaveEvent | 当拖放操作离开窗口小部件时,向窗口小部件发送事件 |
QDragMoveEvent | 当拖放操作正在进行时发送事件 |
QDropEvent | 当拖放操作完成时发送事件 |
QUtiMimeConverter | 在 MIME 类型和统一类型标识符 (UTI) 格式之间进行转换 |
配置
QStyleHints 对象提供了一些与拖放操作相关的属性:
-
QStyleHints::startDragTime() 描述用户在开始拖动之前必须在对象上按住鼠标按钮的时间(以毫秒为单位)。
-
QStyleHints::startDragDistance() 表示用户在按住鼠标按钮的情况下必须将鼠标移动多远,才会将移动解释为拖动。
-
QStyleHints::startDragVelocity() 表示用户必须以多快的速度(以像素/秒为单位)移动鼠标才能开始拖动。值为 0 表示没有这样的限制。
这些数量提供了合理的默认值,这些默认值符合底层窗口系统,如果您在控件中提供拖放支持,则可以使用这些默认值。
拖动
要开始拖动,请创建一个 QDrag 对象并调用其 exec() 函数。在大多数应用程序中,最好仅在按下鼠标按钮并将光标移动一定距离后才开始拖放操作。但是,启用小部件拖动的最简单方法是重新实现小部件的 mousePressEvent() 并开始拖放操作:
void MainWindow::mousePressEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton && iconLabel->geometry().contains(event->pos())) {QDrag *drag = new QDrag(this);QMimeData *mimeData = new QMimeData; mimeData->setText(commentEdit->toPlainText());drag->setMimeData(mimeData);drag->setPixmap(iconPixmap); Qt::DropAction dropAction = drag->exec();...} }
虽然用户可能需要一些时间才能完成拖动操作,但就应用程序而言,exec() 函数是一个阻塞函数,它返回几个值之一。这些值表示操作如何结束,下面将更详细地描述。
请注意,exec() 函数不会阻塞主事件循环。
对于需要区分鼠标单击和拖动的小部件,重新实现小部件的 mousePressEvent() 函数以记录拖动的起始位置很有用:
void DragWidget::mousePressEvent(QMouseEvent *event) {if (event->button() == Qt::LeftButton)dragStartPosition = event->pos(); }
稍后,在 mouseMoveEvent() 中,我们可以确定是否应该开始拖动,并构造一个拖动对象来处理该操作:
void DragWidget::mouseMoveEvent(QMouseEvent *event) {if (!(event->buttons() & Qt::LeftButton)) return;if ((event->pos() - dragStartPosition).manhattanLength() < QApplication::startDragDistance())return; QDrag *drag = new QDrag(this);QMimeData *mimeData = new QMimeData; mimeData->setData(mimeType, data);drag->setMimeData(mimeData); Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);... }
此特定方法使用 QPoint::manhattanLength() 函数粗略估计鼠标单击发生的位置与当前光标位置之间的距离。此函数以速度换取准确性,通常适用于此目的。
放置
为了能够接收放置在小部件上的媒体,请为小部件调用 setAcceptDrops(true),并重新实现 dragEnterEvent() 和 dropEvent() 事件处理程序函数。例如,以下代码在 QWidget 子类的构造函数中启用放置事件,从而可以有效地实现结束拖放
Window::Window(QWidget *parent) : QWidget(parent) {...setAcceptDrops(true); }
dragEnterEvent() 函数通常用于通知 Qt 小部件接受的数据类型。如果您想在重新实现 dragMoveEvent() 和 dropEvent() 时接收 QDragMoveEvent 或 QDropEvent,则必须重新实现此函数。
以下代码显示了如何重新实现 dragEnterEvent() 以告知拖放系统我们只能处理纯文本:
void Window::dragEnterEvent(QDragEnterEvent *event) {if (event->mimeData()->hasFormat("text/plain"))event->acceptProposedAction(); }
dropEvent() 用于解压放置的数据并以适合您的应用程序的方式处理它。在以下代码中,事件中提供的文本被传递给 QTextBrowser,QComboBox 中填充了用于描述数据的 MIME 类型列表:
void Window::dropEvent(QDropEvent *event) {textBrowser->setPlainText(event->mimeData()->text());mimeTypeCombo->clear();mimeTypeCombo->addItems(event->mimeData()->formats()); event->acceptProposedAction(); }
在这种情况下,我们接受建议的操作而不检查它是什么。在实际应用程序中,如果操作不相关,则可能需要从 dropEvent() 函数返回而不接受建议的操作或处理数据。例如,如果我们的应用程序不支持指向外部源的链接,我们可以选择忽略 Qt::LinkAction 操作。
覆盖建议的操作
我们也可以忽略建议的操作,并对数据执行其他操作。为此,我们将在调用 accept() 之前使用 Qt::DropAction 中的首选操作调用事件对象的 setDropAction()。这可确保使用替代放置操作而不是建议的操作。
对于更复杂的应用程序,重新实现 dragMoveEvent() 和 dragLeaveEvent() 将允许您使窗口小部件的某些部分对放置事件敏感,并让您更好地控制应用程序中的拖放。
子类化复杂窗口小部件
某些标准 Qt 窗口小部件提供自己的拖放支持。在子类化这些窗口小部件时,除了 dragEnterEvent() 和 dropEvent() 之外,可能还需要重新实现 dragMoveEvent(),以防止基类提供默认的拖放处理,并处理您感兴趣的任何特殊情况。
拖放操作
在最简单的情况下,拖放操作的目标会收到正在拖动的数据的副本,而源则决定是否删除原始数据。这由 CopyAction 操作描述。目标还可以选择处理其他操作,特别是 MoveAction 和 LinkAction 操作。如果源调用 QDrag::exec(),并且它返回 MoveAction,则源负责删除任何原始数据(如果它选择这样做)。源窗口小部件创建的 QMimeData 和 QDrag 对象不应被删除 - 它们将被 Qt 销毁。目标负责获取拖放操作中发送的数据的所有权;这通常是通过保留对数据的引用来完成的。
如果目标理解 LinkAction 操作,它应该存储自己对原始信息的引用;源不需要对数据执行任何进一步处理。拖放操作最常见的用途是在同一窗口小部件内执行移动;有关此功能的更多信息,请参阅“放置操作”部分。
拖动操作的另一个主要用途是使用引用类型(如 text/uri-list),其中拖动的数据实际上是对文件或对象的引用。
添加新的拖放类型
拖放不仅限于文本和图像。任何类型的信息都可以通过拖放操作进行传输。要在应用程序之间拖动信息,应用程序必须能够相互指示它们可以接受哪些数据格式以及它们可以生成哪些数据格式。这是使用 MIME 类型实现的。源构造的 QDrag 对象包含用于表示数据的 MIME 类型列表(按从最合适到最不合适的顺序排列),而放置目标使用其中一种类型来访问数据。对于常见数据类型,便利函数可以透明地处理所使用的 MIME 类型,但对于自定义数据类型,必须明确说明它们。
要为 QDrag 便利函数未涵盖的信息类型实现拖放操作,第一个也是最重要的步骤是查找现有的合适格式:互联网号码分配机构 (IANA) 在信息科学研究所 (ISI) 提供了 MIME 媒体类型的分层列表。使用标准 MIME 类型可最大限度地提高您的应用程序现在和将来与其他软件的互操作性。要支持其他媒体类型,只需在 QMimeData 中设置数据即可
以下代码从标签中获取像素图并将其作为便携式网络图形 (PNG) 文件存储在 QMimeData 对象中:
QByteArray output; QBuffer outputBuffer(&output); outputBuffer.open(QIODevice::WriteOnly); imageLabel->pixmap().toImage().save(&outputBuffer, "PNG"); mimeData->setData("image/png", output);
当然,对于这种情况,我们可以简单地使用 setImageData() 来提供各种格式的图像数据:
mimeData->setImageData(QVariant(*imageLabel->pixmap()));
QByteArray 方法在这种情况下仍然有用,因为它可以更好地控制 QMimeData 对象中存储的数据量。
请注意,项目视图中使用的自定义数据类型必须声明为元对象,并且必须为它们实现流运算符。
放置操作
在剪贴板模型中,用户可以剪切或复制源信息,然后粘贴。同样,在拖放模型中,用户可以拖动信息的副本,也可以将信息本身拖动到新位置(移动它)。拖放模型给程序员带来了额外的麻烦:程序不知道用户是想剪切还是复制信息,直到操作完成。在应用程序之间拖动信息时,这通常没有区别,但在应用程序内,检查使用了哪种放置操作很重要。
我们可以为小部件重新实现 mouseMoveEvent(),并使用可能的放置操作组合启动拖放操作。例如,我们可能希望确保拖动始终移动小部件中的对象:
void DragWidget::mouseMoveEvent(QMouseEvent *event) {if (!(event->buttons() & Qt::LeftButton))return;if ((event->pos() - dragStartPosition).manhattanLength() < QApplication::startDragDistance())return; QDrag *drag = new QDrag(this);QMimeData *mimeData = new QMimeData; mimeData->setData(mimeType, data);drag->setMimeData(mimeData); Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);... }
如果信息被放入另一个应用程序中,则 exec() 函数返回的操作可能默认为 CopyAction,但如果信息被放入同一应用程序中的另一个小部件中,我们可能会获得不同的放置操作。
可以在小部件的 dragMoveEvent() 函数中过滤建议的放置操作。但是,可以接受 dragEnterEvent() 中提出的所有操作,然后让用户决定稍后要接受哪些操作:
void DragWidget::dragEnterEvent(QDragEnterEvent *event) {event->acceptProposedAction(); }
当小部件中发生放置时,将调用 dropEvent() 处理函数,我们可以依次处理每个可能的操作。首先,我们处理同一个小部件内的拖放操作:
void DragWidget::dropEvent(QDropEvent *event) { if (event->source() == this && event->possibleActions() & Qt::MoveAction)return;
在这种情况下,我们拒绝处理移动操作。我们接受的每种类型的放置操作都会经过检查并进行相应处理:
if (event->proposedAction() == Qt::MoveAction) {event->acceptProposedAction(); // 处理来自事件的数据。 } else if (event->proposedAction() == Qt::CopyAction) {event->acceptProposedAction(); // 处理来自事件的数据。 } else {// 忽略放置。return; } ... }
请注意,我们在上面的代码中检查了单个放置操作。如上文“覆盖建议的操作”部分所述,有时需要覆盖建议的放置操作并从可能的放置操作中选择不同的操作。为此,您需要检查事件的 possibleActions() 提供的值中是否存在每个操作,使用 setDropAction() 设置放置操作,然后调用 accept()。
放置矩形
小部件的 dragMoveEvent() 可用于将放置限制到小部件的某些部分,方法是仅在光标位于这些区域内时才接受建议的放置操作。例如,当光标位于子窗口小部件 (dropFrame) 上时,以下代码将接受任何建议的放置操作:
void Window::dragMoveEvent(QDragMoveEvent *event) {if (event->mimeData()->hasFormat("text/plain") && event->answerRect().intersects(dropFrame->geometry()))event->acceptProposedAction(); }
如果您需要在拖放操作期间提供视觉反馈、滚动窗口或执行任何适当的操作,也可以使用 dragMoveEvent()。
剪贴板
应用程序还可以通过将数据放在剪贴板上来相互通信。要访问此功能,您需要从 QApplication 对象获取 QClipboard 对象。QMimeData 类用于表示传输到剪贴板和从剪贴板传输的数据,要将数据放在剪贴板上,您可以使用 setText()、setImage() 和 setPixmap() 便利函数来处理常见数据类型。这些函数与 QMimeData 类中的函数类似,不同之处在于它们还接受一个额外的参数来控制数据的存储位置:如果指定了 Clipboard,则数据将放在剪贴板上;如果指定了 Selection,则数据将放在鼠标选择中(仅在 X11 上)。默认情况下,数据放在剪贴板上。
例如,我们可以使用以下代码将 QLineEdit 的内容复制到剪贴板:
QGuiApplication::clipboard()->setText(lineEdit->text(), QClipboard::Clipboard);
具有不同 MIME 类型的数据也可以放在剪贴板上。构造一个 QMimeData 对象并使用 setData() 函数设置数据,方法如上所述;然后可以使用 setMimeData() 函数将此对象放在剪贴板上。
QClipboard 类可以通过其 dataChanged() 信号通知应用程序其所含数据的更改。例如,我们可以通过将此信号连接到小部件中的插槽来监视剪贴板:
connect(clipboard, &QClipboard::dataChanged, this, &ClipWindow::updateClipboard);
连接到此信号的插槽可以使用可用于表示它的 MIME 类型之一读取剪贴板上的数据:
void ClipWindow::updateClipboard() {mimeTypeCombo->clear(); QStringList forms = clipboard->mimeData()->formats();if (formats.isEmpty())return; for (const auto &format : forms) {QByteArray data = clipboard->mimeData()->data(format);// ... }
selectionChanged() 信号可用于 X11 上以监视鼠标选择。
其他函数的介绍
关于拖拽和放置,这里有几个方便的函数值得一提:
-
setAcceptDrops(true)
这个函数启用拖放操作,允许窗口小部件接受拖放事件。默认情况下,Qt小部件并不接受拖放数据,因此你需要调用这个函数来启用拖放支持。ui->tableWidget->setAcceptDrops(true);
这样设置之后,
QTableWidget
就会响应拖放事件。 -
setDragDropMode(QAbstractItemView::DragDrop)
这个函数设置了拖放模式,QAbstractItemView::DragDrop
表示启用拖放操作,并允许项目被拖拽和放置。Qt 提供了不同的拖放模式选项:-
QAbstractItemView::NoDragDrop
:不允许拖放操作。 -
QAbstractItemView::DragOnly
:只允许拖拽操作,不能放置。 -
QAbstractItemView::DropOnly
:只允许放置操作,不能拖拽。 -
QAbstractItemView::DragDrop
:同时允许拖拽和放置操作。
你在这里设置的是允许拖拽和放置。
ui->tableWidget->setDragDropMode(QAbstractItemView::DragDrop);
-
-
setDragEnabled(true)
这个函数启用或禁用拖拽操作。true
表示启用拖拽,false
则禁用拖拽。调用该函数后,用户可以从QTableWidget
中拖拽项目。ui->tableWidget->setDragEnabled(true);
-
setDefaultDropAction(Qt::MoveAction)
这个函数设置了默认的拖放操作。Qt::MoveAction
表示在拖拽操作完成后,项目会被移动到目标位置。你也可以选择其他操作:-
Qt::CopyAction
:表示拖拽后复制数据,而不是移动。 -
Qt::MoveAction
:表示拖拽后移动数据。 -
Qt::LinkAction
:表示拖拽后创建链接(通常用于文件和目录)。 -
Qt::ActionMask
:表示一个组合的动作,可以在多个动作之间进行选择。
Qt::MoveAction
是最常见的动作类型,表示项目从原位置移动到新位置。ui->tableWidget->setDefaultDropAction(Qt::MoveAction);
-
这个操作是方便与对默认的行为进行控制。
相关文章:

Qt Event事件系统小探2
目录 事件过滤器 来看一个例子 拖放事件和拖放操作 Qt官方文档给出的说明 拖放 拖放类 配置 拖动 放置 覆盖建议的操作 子类化复杂窗口小部件 拖放操作 添加新的拖放类型 放置操作 放置矩形 剪贴板 其他函数的介绍 事件过滤器 我们知道,有的时候想…...

[2024最新] java八股文实用版(附带原理)---java集合篇
介绍一下常见的list实现类? ArrayList 线程不安全,内部是通过数组实现的,继承了AbstractList,实现了List,适合随机查找和遍历,不适合插入和删除。排列有序,可重复,当容量不够的时候…...

pytorch tensor在CPU和GPU之间转换,numpy之间的转换
# input input.cpu().numpy() input input.cpu().detach().numpy() # 有gradCPU tensor转GPU tensor: cpu_imgs.cuda()GPU tensor 转CPU tensor: gpu_imgs.cpu()numpy转为CPU tensor: torch.from_numpy( imgs )4.CPU tensor转为numpy数…...

【电压分层控制】光储三相并网下垂控制,直流微电网协调母线电压分层控制
摘要 本文研究了一种基于电压分层控制的光伏与储能系统并网控制策略。通过下垂控制和分层控制方法实现直流微电网的协调运行,提高系统动态响应和稳态性能。仿真结果表明,该控制策略能够在不同工况下有效稳定母线电压,并实现负载功率合理分配…...

【CSS】absolute定位的默认位置
position: absolute; 属性会使元素脱离正常的文档流,并相对于最近的非 static 定位祖先元素进行定位。如果没有这样的祖先元素,则相对于初始包含块(通常是视口)进行定位。 但是当top和left没有指定具体值时,元素的在上…...

遗传算法与深度学习实战——利用进化计算优化深度学习模型
遗传算法与深度学习实战——利用进化计算优化深度学习模型 0. 前言1. 利用进化计算优化深度学习模型2. 利用进化策略优化深度学习模型3. 利用差分计算优化深度学习模型相关链接 0. 前言 我们已经学习了使用进化策略 (Evolutionary Strategies, ES) 和差分进化 (Differential E…...

计算机视觉 ---图像读取与显示(OpenCV与Matplotlib)
前言 本文分别介绍了使用 OpenCV 和 Matplotlib 进行图像读取与显示的方法,如 cv2.imread ()、cv2.imshow ()、plt.imread ()、plt.imshow () 等,并提及了使用 OpenCV 时的注意事项。 OpenCV与Matplotlib图像读取与显示的差异 图像读取: Op…...

XML Schema 字符串数据类型
XML Schema 字符串数据类型 1. 概述 XML Schema 是一种用于定义 XML 文档结构和内容的语言。它提供了一种强大的机制来描述 XML 数据的类型、结构和约束。在 XML Schema 中,字符串数据类型是一种基本数据类型,用于表示文本数据。 2. 字符串数据类型 …...

Spring Boot 读取 yml 并映射至实体
application-base.yml app:# 附件存储路径upload-attachments: /data/attachments/# 报告导出详情 url - 前端score-detail-url: ${app.host.web}/#/process/start?processNo{}# api 文件下载 urlfile-download-url: ${app.host.web}/prod-api/sys_file_info/download/{}?fu…...

/// ts中的三斜线指令 | 前端
第一次看到注意到这行代码,不知道的还以为是注释呢,查了资料才知道这是typescript中的三斜线指令,那有什么作用呢? 1. 这行代码是TypeScript中的一个三斜线指令(Triple-Slash Directive),用于…...

什么岗位需要学习 OpenGL ES ?说说 3.X 的新特性
什么是 OpenGL ES OpenGL ES 是一种为嵌入式系统和移动设备设计的3D图形API(应用程序编程接口)。它是标准 OpenGL 3D 图形库的一个子集,专门为资源受限的环境(如手机、平板电脑、游戏机和其他便携式设备)进行了优化。 由于其在移动设备上的广泛适用性,OpenGL ES是学习移…...

【插件】多断言 插件pytest-assume
背景 assert 断言一旦失败,后续的断言不能被执行 有个插件,pytest-assume的插件,可以提供多断言的方式 安装 pip3 install pytest-assume用法 pytest.assume(表达式,f’提示message’) pytest.assume(表达式,f‘提示message’) pytest.ass…...

ctfshow DSBCTF web部分wp
ctfshow 单身杯 web部分wp web 签到好玩的PHP 源码: <?php error_reporting(0); highlight_file(__FILE__);class ctfshow {private $d ;private $s ;private $b ;private $ctf ;public function __destruct() {$this->d (string)$this->d;$this…...

三维点云 和模型转换的问题
随着科技的发展,三维激光扫描采集的点云数据作为一种新型的数据形式,在多个领域中都展现出了其强大的应用价值。那么,什么是点云数据?它是如何生成的?又能为我们的生活和工作带来哪些便利呢? 1.…...

黑马智数Day7
获取行车管理计费规则列表 封装接口 export function getRuleListAPI(params) {return request({url: parking/rule/list,params}) } 获取并渲染数据 import { getRuleListAPI } from /apis/carmounted() {this.getRuleList() }methods: {// 获取规则列表async getRuleList(…...

虚拟机安装Ubuntu 24.04服务器版(命令行版)
这个是专门用于服务器使用的,没有GUI,常用软件安装,见 虚拟机安装Ubuntu 24.04及其常用软件(2024.7)_ubuntu24.04-CSDN博客https://blog.csdn.net/weixin_42173947/article/details/140335522这里只记录独特的安装步骤 1 下载Ubuntu 24.04安…...

.net core开发windows程序在国产麒麟操作系统中运行
.net core自从3.1版本号后,完全是一个独立的开源的多平台开发组件,目前国产化是趋势,不少项目需要开发国产如Kylin操作系统中运行的程序,无论是Web程序还是桌面程序,都有这样的需求。 首先,可明确的的.net…...

【LinuxC编程】06 - 守护进程,线程
进程组和会话 概念和特性 进程组,也称之为作业。BSD于1980年前后向Unix中增加的一个新特性。代表一个或多个进程的集合。每个进程都属于一个进程组。在waitpid函数和kill函数的参数中都曾使用到。操作系统设计的进程组的概念,是为了简化对多个进程的管…...

<websocket><PLC>使用js和html实现webscoket,与PLC进行socket通讯的实例
前言 本文是为了实现从网页端通过websocket与PLC端的socket进行数据通讯。 环境配置 系统:windows 平台:visual studio code 语言:javascript、html、PLC 库:node.js 概述 本文的目的是通过网页端与PLC进行socket通讯,但web端一般并不是直接使用socket,而是websocket,…...

nginx部署H5端程序与PC端进行区分及代理多个项目及H5内页面刷新出现404问题。
在项目中会碰见需要在nginx代理多个项目,如果在加上uniapp开发的H5端的项目,你还要在nginx中区分PC端和手机H5端,这就会让人很头大!网上大部分的资料都是采用在nginx的conf配置文件中添加区分pc和手机端的变量例如:set…...

blenderFds代码解读
文章目录 一. 介绍1. FDS(Fire Dynamics Simulator)2. BlenderFDS 二. 下载代码三. 开发环境配置四. 代码解读1. blender python特有语法2. 代码结构2.1 变量名解释2.2 bl文件夹operators文件夹ui其他文件 2.2 lang文件夹bf_sceneON_GEOMON_MESHON_MOVEO…...

亚马逊评论爬虫+数据分析
爬取评论 做分析首先得有数据,数据是核心,而且要准确! 1、爬虫必要步骤,选好框架 2、开发所需数据 3、最后测试流程 这里我所选框架是seleniumrequest,很多人觉得selenium慢,确实不快,仅针对此…...

新手小白学习docker第六弹------Docker常规安装(安装tomcat、mysql、redis)
目录 1 总体步骤2 安装tomcat2.1 搜索镜像2.2 拉取镜像2.3 查看镜像2.4 启动镜像2.5 访问猫首页 3 安装mysql3.1 搜索镜像3.2 拉取镜像3.3 启动镜像 4 安装redis4.1 拉取镜像4.2 启动镜像(法1基础版)4.3 配置文件4.3.1 在宿主机下新建目录 /app/redis4.3…...

ReactPress与WordPress:两大开源发布平台的对比与选择
ReactPress与WordPress:两大开源发布平台的对比与选择 在当今数字化时代,内容管理系统(CMS)已成为各类网站和应用的核心组成部分。两款备受欢迎的开源发布平台——ReactPress和WordPress,各自拥有独特的优势和特点&am…...

机器情绪及抑郁症算法
🏡作者主页:点击! 🤖编程探索专栏:点击! ⏰️创作时间:2024年11月12日17点02分 点击开启你的论文编程之旅https://www.aspiringcode.com/content?id17230869054974 计算机来理解你的情绪&a…...

01-Ajax入门与axios使用、URL知识
欢迎来到“雪碧聊技术”CSDN博客! 在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将…...

第四十五章 Vue之Vuex模块化创建(module)
目录 一、引言 二、模块化拆分创建方式 三、模块化拆分完整代码 3.1. index.js 3.2. module1.js 3.3. module2.js 3.4. module3.js 3.5. main.js 3.6. App.vue 3.7. Son1.vue 3.8. Son2.vue 四、访问模块module的state 五、访问模块中的getters 六、mutati…...

[2024最新] macOS 发起 Bilibili 直播(不使用 OBS)
文章目录 1、B站账号 主播认证2、开启直播3、直播设置添加素材、隐私设置指定窗口添加/删除 窗口 4、其它说明官方直播帮助中心直播工具教程 目前搜到的 macOS 直播教程都比较古早,大部分都使用 OBS,一番探索下来,发现目前已经不需要 OBS了&a…...

Netty实现WebSocket Client三种典型方式
一、简单版本 package com.ptc.ai.box.biz.relay.client;import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext;…...

软间隔支持向量机
软间隔支持向量机 我们先直接给出软间隔支持向量机的形式: P min ω , b , ζ 1 2 ∥ ω ∥ 2 2 − C ∑ i 1 m ζ i s . t . y i ( ω x i b ) ≥ 1 − ζ i , i 1 , 2 , 3.. m ζ i ≥ 0 , i 1 , 2 , 3.. m P \min_{\omega,b,\zeta} \frac{1}{2}\Ve…...