QT c++和qml交互实例
文章目录
- 一、demo效果图
- 二、c++和qml交互的基本方式
- 1、qml 调用 C++ 类对象
- 2、C++ 类对象调用 qml
- 3、qml 给 C++ 发送信号
- 4、C++ 给 qml 发送信号
- 三、关键代码
- 1、工程结构图
- 2、c++代码
- MainWindow.cpp
- MainQuickView.cpp
- StudentInfoView.cpp
- StudentInfoModel.cpp
- 3、qml代码
- main.qml
- MainQuickTopRect.qml
- MainQuickMiddleRect.qml
- MainQuickMiddleTableRect.qml
一、demo效果图
该实例,主要是在已有的QWidget工程中,加入qml工程,方便qml项目的开发与维护,让qml开发者更好的上手qml。
(1)展示了c++和qml常见的交互方式。
(2)qwidget工程如何加载qml工程,如何加载自己实现的qml tool库。
(3)创建无边框qml界面,支持拖拽,窗口的缩小与展开,界面的分段实现。
(4)展示一个简单的堆栈窗口(SwipeView),相当于QStackedWidget,管理多个子窗口页面。
(5)实现一个简单的列表框(ListView),相当于QListWidget,定时请求网络数据,展示学生信息,将view和model进行分离,降低界面与数据的耦合。
(6)点击学号、年龄,实现了列表数据的排序。
二、c++和qml交互的基本方式
两者的交互是核心,简单学习后,可以快速上手。方式有很多种,有的比较繁杂,不易理解,此处只使用了最方便使用的方法,满足基本的交互。基本的方式不外乎有四种。
- qml 调用 C++ 类对象
- C++ 类对象调用 qml
- qml 给 C++ 发送信号
- C++ 给 qml 发送信号
1、qml 调用 C++ 类对象
需要先将C++类(MainQuickView、MyWindow)注册。和qml相关的C++类,最好都进行注册。
// cpp
class MainQuickView : public QQuickView
{Q_OBJECT
public:MainQuickView(QQuickView *parent = nullptr);~MainQuickView() override;void initialzeUI();
protected:
};void MainQuickView ::initialzeUI()
{// 注册,为了qml中可以直接访问C++对象this->rootContext()->setContextProperty("myQuickView", this);MyWindow *w = new MyWindow();this->rootContext()->setContextProperty("myWindow", w);...
}
这样C++的信号
,public槽函数
,Q_INVOKABLE 修饰的类成员函数
// cpp
class MyWindow : public QWidget
{Q_OBJECTpublic:MyWindow();// Q_INVOKABLE可以将C++函数暴漏给qml引擎,注册到元对象系统Q_INVOKABLE void invokableMethod();signals:void dataChanged();public slots:void refresh();
};
就可以在qml中调用
// main.qml
Rectangle {id: rootwidth: 1200height: 800onClicked: {myWindow.showNormal(); // showNormal是QWidget父类的槽函数}
}
2、C++ 类对象调用 qml
需要先找到你想访问的qml中,名为"topRect"的QQuickItem对象
// cpp
QQuickItem* topRect = this->rootObject()->findChild<QQuickItem*>("topRect");
然后再访问qml实现的函数,“setTitleText”,该函数标题3展示(qml 给 C++ 发送信号)
// cpp
QMetaObject::invokeMethod(topRect, "setTitleText", Q_ARG(QVariant, QString::fromLocal8Bit("Qml窗口标题")));
3、qml 给 C++ 发送信号
qml发送信号
// qml
Rectangle {id: rootsignal sendTopRectPos(var x, var y) // 定义信号function setTitleText(text) {titleText.text = text}MouseArea {// ... property point clickPos: "0, 0"onPressed: {clickPos = Qt.point(mouse.x, mouse.y)}onPositionChanged: {var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)sendTopRectPos(delta.x, delta.y) // 发送信号}}
}
C++绑定槽函数,该操作可以实现无边框窗口的拖拽
// cpp
QQuickItem* topRect = this->rootObject()->findChild<QQuickItem*>("topRect");if (topRect) {connect(topRect, SIGNAL(sendTopRectPos(QVariant, QVariant)),this, SLOT(onSendTopRectPos(QVariant, QVariant)));
4、C++ 给 qml 发送信号
C++发送信号
// cpp
void MainQuickView::minMaxQmlWindow()
{int nStudent = 10;emit refreshStuCount(nStudent); // 发送信号
}
qml绑定槽函数
// qml
Rectangle {id: rootfunction onRefreshStuCount(nStudent){// ...}Component.onCompleted: {mainQuickView.refreshStuCount.connect(onRefreshStuCount) // 绑定qml函数}
三、关键代码
1、工程结构图
2、c++代码
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent): QWidget(parent), ui(new Ui::MainWindow), m_pQuickVew(nullptr)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{if (!m_pQuickVew){// 加载qml包含两种方式,一种是QQuickView,一种是QQmlApplicationEngine// 当前使用第一种方式,MainQuickView继承自QQuickViewm_pQuickVew = new MainQuickView();m_pQuickVew->setObjectName("quickView");}m_pQuickVew->show();
}
MainQuickView.cpp
static const char* s_mainPath = "qrc:/qml/main.qml";MainQuickView::MainQuickView(QQuickView *parent): QQuickView(parent), m_bMin(false)
{this->setFlags(Qt::Window | Qt::FramelessWindowHint);this->setTitle(QString::fromLocal8Bit("图书馆"));initialize();setMoveable();setTitleData();
}MainQuickView::~MainQuickView()
{
}void MainQuickView::initialize()
{// 初始化view 和 model,降低耦合,提高可维护性if (!m_pStudentInfoView)m_pStudentInfoView = new StudentInfoView();if (!m_pStudentInfoModel)m_pStudentInfoModel = m_pStudentInfoView->getStudentInfoMode();// ...其他功能initialzeUI();
}void MainQuickView::initialzeUI()
{// 注册,qml中可以直接访问C++对象this->rootContext()->setContextProperty("mainQuickView", this);// qml可以通过"studentInfoView",去使用其实现的函数this->rootContext()->setContextProperty("studentInfoView", m_pStudentInfoView);this->rootContext()->setContextProperty("studentInfoModel", m_pStudentInfoModel);// qml根对象大小随窗口大小改变而改变this->setResizeMode(QQuickView::SizeRootObjectToView);// 导入自定义模块工具this->engine()->addImportPath(":/qmlTools");// 设置准备加载得qml文件,相当于c++的main函数入口this->setSource(QUrl(s_mainPath));
}void MainQuickView::minMaxQmlWindow()
{m_bMin = !m_bMin;emit minQmlWindow(m_bMin);
}void MainQuickView::onSendTopRectPos(QVariant pX, QVariant pY)
{this->setX(this->x() + pX.toInt());this->setY(this->y() + pY.toInt());
}void MainQuickView::onCloseQuickView()
{close();
}void MainQuickView::onShowMinimized()
{showMinimized();
}void MainQuickView::setMoveable()
{// 当移动qml窗口时,将移动坐标告诉C++// 找到对象名叫topRect的qml,C++绑定qml的信号QQuickItem* topRect = this->rootObject()->findChild<QQuickItem*>("topRect");if (topRect) {connect(topRect, SIGNAL(sendTopRectPos(QVariant, QVariant)),this, SLOT(onSendTopRectPos(QVariant, QVariant)));}
}void MainQuickView::setTitleData()
{// 找到对象名叫topRect的qml,C++向qml发送消息,触发qml中实现的setTitleText函数QQuickItem* topRect = this->rootObject()->findChild<QQuickItem*>("topRect");QMetaObject::invokeMethod(topRect, "setTitleText", Q_ARG(QVariant, QString::fromLocal8Bit("Qml窗口标题")));
}
StudentInfoView.cpp
StudentInfoView::StudentInfoView(QObject *parent): QObject(parent), m_sortType(StudentInfoSort::sortNone)
{if (!m_pStudentInfoModel)m_pStudentInfoModel = new StudentInfoModel(this);// 如果数据来自网络,就需要定时请求接口,并更新界面m_timer = new QTimer(this);m_timer->setInterval(10 * 1000);QObject::connect(m_timer, &QTimer::timeout, this, &StudentInfoView::onUpdateInfoData);onUpdateInfoData();m_timer->start();
}StudentInfoModel *StudentInfoView::getStudentInfoMode()
{return m_pStudentInfoModel;
}// qSort()比较函数不能定义为类成员函数(参数包含隐藏的this指针),会导致参数不符
// 可以定义为static类成员函数、static函数、普通函数
bool StudentInfoView::idAscend(const StudentInfoItem &stu1, const StudentInfoItem &stu2)
{return stu1.stuId < stu2.stuId; //学号升序
}// 普通函数
bool idDescend(const StudentInfoItem &stu1, const StudentInfoItem &stu2)
{return stu1.stuId > stu2.stuId; //学号降序
}bool ageAscend(const StudentInfoItem &stu1, const StudentInfoItem &stu2)
{return stu1.age < stu2.age; //年龄升序
}void StudentInfoView::setSort(StudentInfoSort sortType)
{m_sortType = sortType;if (m_sortType == StudentInfoSort::sortIdAscend){qSort(m_allDatas.begin(), m_allDatas.end(), idAscend);}else if (m_sortType == StudentInfoSort::sortIdDescend){qSort(m_allDatas.begin(), m_allDatas.end(), idDescend);}else if (m_sortType == StudentInfoSort::sortAgeAscend){// 比较函数也可以写为lambda表达式qSort(m_allDatas.begin(), m_allDatas.end(),[](const StudentInfoItem& stu1, const StudentInfoItem& stu2){return stu1.age < stu2.age;});}
}void StudentInfoView::updateSort(int sortType)
{// qml调用,执行哪一种排序方式,并刷新数据setSort((StudentInfoSort)sortType);if (m_pStudentInfoModel)m_pStudentInfoModel->clear();for (auto studentInfo : m_allDatas) {if (m_pStudentInfoModel) {m_pStudentInfoModel->AddModel(studentInfo);}}
}void StudentInfoView::onUpdateInfoData()
{// 每隔十秒请求网络接口,根据返回的数据刷新model,该实例模拟网络数据m_allDatas.clear();if (m_pStudentInfoModel)m_pStudentInfoModel->clear();QVector<StudentInfoItem> studentInfos;StudentInfoItem item1;item1.stuId = 9704;item1.stuName = QString::fromLocal8Bit("百里");item1.sex = 1;item1.age = 14;StudentInfoItem item2;item2.stuId = 9207;item2.stuName = QString::fromLocal8Bit("黄忠");item2.sex = 1;item2.age = 26;StudentInfoItem item3;item3.stuId = 9206;item3.stuName = QString::fromLocal8Bit("鲁班");item3.sex = 1;item3.age = 17;StudentInfoItem item4;item4.stuId = 9787;item4.stuName = QString::fromLocal8Bit("女娲");item4.sex = 0;item4.age = 33;studentInfos << item1 << item2 << item3 << item4;m_allDatas = studentInfos;setSort(m_sortType); //每一次网络数据刷新后,执行保存的排序方式for (auto studentInfo : m_allDatas) {if (m_pStudentInfoModel) {m_pStudentInfoModel->AddModel(studentInfo);}}
}
StudentInfoModel.cpp
#include "StudentInfoModel.h"StudentInfoModel::StudentInfoModel(QObject *parent): QAbstractListModel(parent)
{roleNames();
}StudentInfoModel::~StudentInfoModel()
{}void StudentInfoModel::clear()
{if (m_allDatas.size() <= 0)return;beginRemoveRows(QModelIndex(), 0, m_allDatas.size() - 1);m_allDatas.clear();endRemoveRows();
}void StudentInfoModel::mremove(int index)
{beginRemoveRows(QModelIndex(), index, index);m_allDatas.erase(m_allDatas.begin() + index);endRemoveRows();
}void StudentInfoModel::update(int index, const StudentInfoItem &infoModel)
{if (index < 0 || m_allDatas.size() < index)return;StudentInfoItem &srcModel = m_allDatas[index];srcModel = infoModel;
}void StudentInfoModel::AddModel(const StudentInfoItem &md)
{beginInsertRows(QModelIndex(), rowCount(), rowCount());m_allDatas.push_back(md);endInsertRows();
}QVariant StudentInfoModel::data(const QModelIndex &index, int role) const
{if (index.row() < 0 || index.row() >= m_allDatas.size()) {return QVariant();}const StudentInfoItem &itemInfo = m_allDatas.at(index.row());StudentInfoRoles infoRole = static_cast<StudentInfoRoles>(role);switch (infoRole) {case StudentInfoRoles::stuIdRole :return itemInfo.stuId;break;case StudentInfoRoles::stuNameRole :return itemInfo.stuName;break;case StudentInfoRoles::stuSexRole :return itemInfo.sex;break;case StudentInfoRoles::stuAgeRole :return itemInfo.age;break;default:return QVariant();break;}
}int StudentInfoModel::rowCount(const QModelIndex &parent) const
{return m_allDatas.size();
}QHash<int, QByteArray> StudentInfoModel::roleNames() const
{// 映射C++端的枚举与QML端的字符串QHash<int, QByteArray> data;data[int(StudentInfoRoles::stuIdRole)] = "stuId";data[int(StudentInfoRoles::stuNameRole)] = "stuName";data[int(StudentInfoRoles::stuSexRole)] = "sex";data[int(StudentInfoRoles::stuAgeRole)] = "age";return data;
}
3、qml代码
main.qml
import QtQuick 2.0
import QtQuick.Layouts 1.0Item {id: rootwidth: 1200height: 800Rectangle {anchors.fill: parentcolor: "red"ColumnLayout {spacing: 0MainQuickTopRect {id: topRectobjectName: "topRect"width: root.widthheight: 50}MainQuickMiddleRect {id: middleRectobjectName: "middleRect"width: root.widthheight: root.height - topRect.height}}}
}
MainQuickTopRect.qml
import QtQuick 2.12
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.12
import "../qmlTools/ButtonTools"Rectangle {id: rootcolor: "#181D33"signal sendTopRectPos(var x, var y)function setTitleText(text) {titleText.text = text}function onMinQmlWindow(bMin){if (bMin)narrowBtn.clicked() // narrowBtn是最小化按钮,当然也可以直接mainQuickView.onShowMinimized()elsemainQuickView.showNormal()}Component.onCompleted: {mainQuickView.minQmlWindow.connect(onMinQmlWindow)}RowLayout {id: rowLayoutanchors.fill: rootanchors.leftMargin: 16anchors.rightMargin: 16Text {id: titleTextanchors.fill: rootanchors.left: rowLayout.leftverticalAlignment: Text.AlignVCenterhorizontalAlignment: Text.AlignHCentercolor: "white"font.pixelSize: 18font.family: "Microsoft YaHei UI"font.bold: truetext: ""// 设置文本框背景颜色Rectangle {id: titleTextBackanchors.fill: titleTextcolor: "#000000"z: -1}}// 最小化ImageBtn {id: narrowBtnwidth: 24height: 24anchors.right: closeBtn.leftnormalUrl: "qrc:/resource/minNormal.png"hoveredUrl: "qrc:/resource/minHover.png"pressedUrl: "qrc:/resource/minHover.png"onClicked: {mainQuickView.onShowMinimized();console.log("min");}}// 关闭ImageBtn {id: closeBtnwidth: 24height: 24anchors.right: rowLayout.rightnormalUrl: "qrc:/resource/closeNormal.png"hoveredUrl: "qrc:/resource/closeHover.png"pressedUrl: "qrc:/resource/closeHover.png"onClicked: {mainQuickView.onCloseQuickView();}}}MouseArea {anchors.fill: parentacceptedButtons: Qt.LeftButtonpropagateComposedEvents: true //传递鼠标事件property point clickPos: "0, 0"onPressed: {clickPos = Qt.point(mouse.x, mouse.y)console.log("onPressed " + clickPos);}onPositionChanged: {var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)sendTopRectPos(delta.x, delta.y)}}
}
MainQuickMiddleRect.qml
import QtQuick 2.0
import QtQuick 2.12
import QtQuick.Controls 1.2
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.2
import "../qmlTools/ButtonTools"Rectangle {id: rootcolor: "#2E3449"property int oneCount: 50property int twoCount: 50property int threeCount: 50readonly property int pageWidth : 400Rectangle {id: titleSwitchBtnwidth: parent.width / 2anchors.top: parent.topanchors.topMargin: 30anchors.left: parent.leftanchors.leftMargin: width - width / 2height: 46color: "#2C5CA5"RowLayout {spacing: 20anchors.bottom: parent.bottomanchors.bottomMargin: 0anchors.left: parent.leftanchors.leftMargin: 40DownLineBtn { // qmlTool中自定义实现的下划线按钮id: cover_one_btnbtn_width: 100btn_string: qsTr("一班") + oneCount + qsTr("人")onMyClicked: {coverBtnStat(cover_one_btn, true)coverBtnStat(cover_two_btn, false)coverBtnStat(cover_three_btn, false)swipeView.currentIndex = 0}}DownLineBtn {id: cover_two_btnbtn_width: 100btn_string: qsTr("二班") + twoCount + qsTr("人")onMyClicked: {coverBtnStat(cover_one_btn, false)coverBtnStat(cover_two_btn, true)coverBtnStat(cover_three_btn, false)swipeView.currentIndex = 1}}DownLineBtn {id: cover_three_btnbtn_width: 100btn_string: qsTr("三班") + threeCount + qsTr("人")onMyClicked: {coverBtnStat(cover_one_btn, false)coverBtnStat(cover_two_btn, false)coverBtnStat(cover_three_btn, true)swipeView.currentIndex = 2}}}}Rectangle {id: viewanchors.top: titleSwitchBtn.bottomanchors.topMargin: 4anchors.left: titleSwitchBtn.leftwidth: titleSwitchBtn.widthheight: pageWidthcolor: "white"radius: 4SwipeView {id: swipeViewobjectName: "outSideSwipView"anchors.fill: parentcurrentIndex: 0clip: true //隐藏未选中的界面interactive: false //鼠标能否滑动Item { //St: 0,第一页id: onePageRectangle {id: oneViewanchors.fill: parentcolor: "#D7B9A1"}}Item { //St: 1,第二页id: twoPageMainQuickMiddleTableRect {id: tableViewcolor: "green"width: titleSwitchBtn.widthheight: pageWidth}}Item { //St: 2,第三页id: defaultPageRectangle {anchors.fill: parentcolor: "#E6EC12"radius: 4Text {text: qsTr("没有数据")font.pixelSize:16color: "red"font.family: "Microsoft YaHei"verticalAlignment: Text.AlignVCenterhorizontalAlignment: Text.AlignHCenteranchors.verticalCenter: parent.verticalCenteranchors.horizontalCenter: parent.horizontalCenter}}}}}Component.onCompleted: {// 初始化按钮状态coverBtnStat(cover_one_btn, true)coverBtnStat(cover_two_btn, false)coverBtnStat(cover_three_btn, false)}/* btn: object* st : modify state*/function coverBtnStat(btn, st) {btn.bold_st = stbtn.show_line = st}
}
MainQuickMiddleTableRect.qml
import QtQuick 2.0
import "../qmlTools/ButtonTools"
import QtQuick.Controls 1.4
import QtQuick.Controls 2.5Rectangle {id: winanchors.fill: parentcolor: "green"property var current_numbers : 0property var stu_id_sort_state : 1property var stu_id_sort_open : false// 绘制表头Rectangle {id: table_Headheight: 48anchors.top: titleSwitchBtn.bottomRectangle {id: table_Textheight: 47 // 比整个表头高度小1,为了容纳下划线TextShow {id: name_texttext: qsTr("姓名")anchors.left: table_Text.leftanchors.leftMargin: 68anchors.verticalCenter: table_Text.verticalCenter}TextShow {id: id_text// 学号未点击时,显示"↕",表示不排序,点击后再判断时升序还是降序text: qsTr("学号") + (!stu_id_sort_open ?qsTr("↕") :(stu_id_sort_state ? qsTr("↓") : qsTr("↑")))anchors.left: table_Text.leftanchors.leftMargin: 150anchors.verticalCenter: table_Text.verticalCenterMouseArea {anchors.fill: parentpropagateComposedEvents: trueonPressed: {console.log("student id clicked")studentInfoView.updateSort(stu_id_sort_state ? 1 : 2) // 通知C++修改排序方式stu_id_sort_state = !stu_id_sort_statestu_id_sort_open = true}}}TextShow {id: sex_texttext: qsTr("性别")anchors.left: table_Text.leftanchors.leftMargin: 220anchors.verticalCenter: table_Text.verticalCenter}TextShow {id: age_texttext: qsTr("年龄")anchors.left: table_Text.leftanchors.leftMargin: 290anchors.verticalCenter: table_Text.verticalCenterMouseArea {anchors.fill: parentpropagateComposedEvents: trueonPressed: {console.log("student age clicked")studentInfoView.updateSort(3)stu_id_sort_open = false}}}LongLine {anchors.top: table_Text.bottom}}}//listViewRectangle {width: parent.widthheight: parent.height - table_Head.heightcolor: "green"anchors.top: table_Head.bottomListView {id: list_viewanchors.rightMargin: 10anchors.bottomMargin: 50anchors.leftMargin: 0anchors.topMargin: 0anchors.fill: parentmaximumFlickVelocity: 800clip: truedelegate: studentInfoDelegatemodel: studentInfoModelboundsBehavior: Flickable.StopAtBoundshighlightMoveDuration: 0ScrollBar.vertical: ScrollBar {id: scrollbar//visible: (current_numbers > 8)visible: trueanchors.right: list_view.rightwidth: 8active: truebackground: Item {Rectangle {anchors.right: parent.rightheight: parent.heightcolor: "yellow"radius: 4}}contentItem: Rectangle {radius: 4color: "red"}}}//studentInfoDelegate 渲染每一个itemComponent {id: studentInfoDelegateRectangle {id: list_itemwidth: parent.widthheight: 46color: "green"Rectangle {width: parent.widthheight: parent.heightcolor: "green"anchors.verticalCenter: parent.verticalCenterRectangle {id: rect_itemcolor: "#333333"height: 45TextShow {id: stu_nametext: model.stuNameanchors.verticalCenter: rect_item.verticalCenteranchors.left: rect_item.leftanchors.leftMargin: 68}TextShow {id: id_typetext: model.stuIdanchors.verticalCenter: rect_item.verticalCenteranchors.left: rect_item.leftanchors.leftMargin: 150}TextShow {id: sex_typetext: (model.sex == 1) ? qsTr("男") : qsTr("女")anchors.verticalCenter: rect_item.verticalCenteranchors.left: rect_item.leftanchors.leftMargin: 220}TextShow {id: age_typetext: model.age + qsTr(" 岁")anchors.verticalCenter: rect_item.verticalCenteranchors.left: rect_item.leftanchors.leftMargin: 290}}LongLine {anchors.top: rect_item.bottom}}}}}Component.onCompleted: {// qml加载完成后,可以获取C++中数据的个数,用来标识是否需要展示滚动条current_numbers = 4}
}
相关文章:

QT c++和qml交互实例
文章目录 一、demo效果图二、c和qml交互的基本方式1、qml 调用 C 类对象2、C 类对象调用 qml3、qml 给 C 发送信号4、C 给 qml 发送信号 三、关键代码1、工程结构图2、c代码MainWindow.cppMainQuickView.cppStudentInfoView.cppStudentInfoModel.cpp 3、qml代码main.qmlMainQui…...

mysql基础-数据操作之增删改
目录 1.新增数据 1.1单条数据新增 1.2多条数据新增 1.3查询数据新增 2.更新 2.1单值更新 2.2多值更新 2.3批量更新 2.3.1 批量-单条件更新 2.3.2批量-多条件更新 2.4 插入或更新 2.5 联表更新 3.删除 本次分享一下数据库的DML操作语言。 操作表的数据结构…...
写字母(文件)
请编写函数,将大写字母写入文件中。 函数原型 void WriteLetter(FILE *f, int n);说明:参数 f 为文件指针,n 为字母数目(1 ≤ n ≤ 26)。函数将前 n 个大写英文字母写入 f 所指示的文件中。 裁判程序 #include <stdio.h> #include &…...

基于Jackson自定义json数据的对象转换器
1、问题说明 后端数据表定义的id主键是Long类型,一共有20多位。 前端在接收到后端返回的json数据时,Long类型会默认当做数值类型进行处理。但前端处理20多位的数值会造成精度丢失,于是导致前端查询数据出现问题。 测试前端Long类型的代码 …...
【Java】缓存击穿解决方案
文章目录 什么是SingleFlight?优化缺点优化策略 什么是SingleFlight? SingleFlight是go语言中sync包中的一个东西。它用于确保在并发环境下某个操作(例如,函数调用)即使被多个goroutine同时请求,也只会被执…...

【HarmonyOS】掌握 Stage 模型的核心概念与应用
从今天开始,博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”,对于刚接触这项技术的小伙伴在学习鸿蒙开发之前,有必要先了解一下鸿蒙,从你的角度来讲,你认为什么是鸿蒙呢?它出现的意义又是…...

2024年甘肃省职业院校技能大赛 “信息安全管理与评估”赛项样题卷①
2024年甘肃省职业院校技能大赛 高职学生组电子与信息大类信息安全管理与评估赛项样题 第一阶段:第二阶段:模块二 网络安全事件响应、数字取证调查、应用程序安全第二阶段 网络安全事件响应第一部分 网络安全事件响应第二部分 数字取证调查第三部分 应用程…...

我的AI之旅开始了
知道重要,但是就是不动。 今天告诉自己,必须开始学习了。 用这篇博文作为1月份AI学习之旅的起跑点吧。 从此,无惧AI,无惧编程。 AI之路就在脚下。 AI,在我理解,就是让机器变得更加智能&#…...
Day25 235二叉搜索树的公共祖先 701二叉搜索树插入 450二叉搜索树删除
235 二叉搜索树的最近公共祖先 如果利用普通二叉树的方法,就是利用后序遍历回溯从低向上搜索,遇到左子树有p,右子树有q,那么当前结点就是最近公共祖先。本题是二叉搜索树,所以说是有序的,一定能够简化上面…...
android系列-init 挂载文件系统
1.init 挂载文件系统 //android10\system\core\init\main.cppint main(int argc, char** argv) {return FirstStageMain(argc, argv); } //android10\system\core\init\first_stage_init.cppint FirstStageMain(int argc, char** argv) {CHECKCALL(mount("tmpfs",…...

Spring 七种事务传播性介绍
作者:vivo 互联网服务器团队 - Zhou Shaobin 本文主要介绍了Spring事务传播性的相关知识。 Spring中定义了7种事务传播性: PROPAGATION_REQUIRED PROPAGATION_SUPPORTS PROPAGATION_MANDATORY PROPAGATION_REQUIRES_NEW PROPAGATION_NOT_SUPPORTED…...
Count the Colors ZOJ - 1610
题目链接 题意: 给定n个区间[ l, r ]和颜色c, 每次给[l, r]涂上c这个颜色. 后面的涂色会覆盖之前的涂色. 最后要求输出区间[0, 8000]中每种颜色及其出现的次数, 如果该颜色没有出现过则不输出. 思路:典型的线段树区间染色问题,一般这种题…...
MATLAB点云处理总目录
一、点云滤波 原始点云包含过多噪点和冗余点,滤波和采样往往是点云预处理的必要步骤 1.滤波 重复点去除 NAN或INF无效点去除 自定义半径滤波 2.采样 基于空间格网的点云抽稀 随机下采样 均匀体素下采样 非均匀体素下采样 二、邻近搜索 如何组织点云快速获取当前…...
C语言逗号表达式如何计算
在 C 语言中,逗号表达式是一种特殊的表达式形式,它由逗号分隔的多个表达式组成。 逗号表达式的计算过程如下:1、从左到右依次计算每个表达式的值。2、最终返回的值是最右边表达式的值。3、逗号表达式的求值过程是顺序执行的,不会…...

Ubuntu 本地部署 ChatGPT-Next-Web
Ubuntu 本地部署 ChatGPT-Next-Web 文章目录 Ubuntu 本地部署 ChatGPT-Next-Web ChatGPT-Next-Web 项目地址:https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web 本文主要演示如何在 Ubuntu 本地(默认是端口 3000)部署 ChatGPT-Next-Web&am…...

小程序商城搭建:快速入门指南
随着移动互联网的普及,小程序商城逐渐成为了商家们进行线上销售的重要渠道。如果你也想搭建一个小程序商城,那么本文将为你介绍如何使用乔拓云这一第三方小程序搭建平台来轻松搭建自己的小程序商城。 一、选择合适的第三方小程序搭建平台 在选择第三方小…...

c# windows10大小端试
测试代码: unsafe public void ceshi() {byte[] by BitConverter.GetBytes(0x12345678);Debug.WriteLine(" byte[0] 0x" by[0].ToString("x2"));Debug.WriteLine(" byte[1] 0x" by[1].ToString("x2"));Debug.WriteLi…...
【算法专题】动态规划之斐波那契数列模型
动态规划1.0 动态规划 - - - 斐波那契数列模型1. 第 N 个泰波那契数2. 三步问题3. 使用最小花费爬楼梯4. 解码方法 动态规划 - - - 斐波那契数列模型 1. 第 N 个泰波那契数 题目链接 -> Leetcode -1137. 第 N 个泰波那契数 Leetcode -1137. 第 N 个泰波那契数 题目&…...

K2P路由器刷OpenWrt官方最新版本固件OpenWrt 23.05.2方法 其他型号的智能路由器OpenWrt固件刷入方法也基本上适用
最近路由器在开机时总出问题,于是就那他来开刀,直接刷一个OpenWrt官方最新版本的固件, 刷其他第三方的固件总是觉得不安全, 而且很多第三方固件都带了些小工具,始终会有安全隐患, 而且占用内存空间太多,本来这个东西就没有多少内存,于是就干脆刷一个官方的原始固件(才6.3M, 相…...

AI大语言模型会带来了新一波人工智能浪潮?
以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮,可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

Linux入门(十五)安装java安装tomcat安装dotnet安装mysql
安装java yum install java-17-openjdk-devel查找安装地址 update-alternatives --config java设置环境变量 vi /etc/profile #在文档后面追加 JAVA_HOME"通过查找安装地址命令显示的路径" #注意一定要加$PATH不然路径就只剩下新加的路径了,系统很多命…...

MLP实战二:MLP 实现图像数字多分类
任务 实战(二):MLP 实现图像多分类 基于 mnist 数据集,建立 mlp 模型,实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入,可视化图形数字; 2、完成数据预处理:图像数据维度转换与…...