当前位置: 首页 > news >正文

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操作语言。 操作表的数据结构&#xf…...

写字母(文件)

请编写函数&#xff0c;将大写字母写入文件中。 函数原型 void WriteLetter(FILE *f, int n);说明&#xff1a;参数 f 为文件指针&#xff0c;n 为字母数目(1 ≤ n ≤ 26)。函数将前 n 个大写英文字母写入 f 所指示的文件中。 裁判程序 #include <stdio.h> #include &…...

基于Jackson自定义json数据的对象转换器

1、问题说明 后端数据表定义的id主键是Long类型&#xff0c;一共有20多位。 前端在接收到后端返回的json数据时&#xff0c;Long类型会默认当做数值类型进行处理。但前端处理20多位的数值会造成精度丢失&#xff0c;于是导致前端查询数据出现问题。 测试前端Long类型的代码 …...

【Java】缓存击穿解决方案

文章目录 什么是SingleFlight&#xff1f;优化缺点优化策略 什么是SingleFlight&#xff1f; SingleFlight是go语言中sync包中的一个东西。它用于确保在并发环境下某个操作&#xff08;例如&#xff0c;函数调用&#xff09;即使被多个goroutine同时请求&#xff0c;也只会被执…...

【HarmonyOS】掌握 Stage 模型的核心概念与应用

从今天开始&#xff0c;博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”&#xff0c;对于刚接触这项技术的小伙伴在学习鸿蒙开发之前&#xff0c;有必要先了解一下鸿蒙&#xff0c;从你的角度来讲&#xff0c;你认为什么是鸿蒙呢&#xff1f;它出现的意义又是…...

2024年甘肃省职业院校技能大赛 “信息安全管理与评估”赛项样题卷①

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

我的AI之旅开始了

知道重要&#xff0c;但是就是不动。 今天告诉自己&#xff0c;必须开始学习了。 用这篇博文作为1月份AI学习之旅的起跑点吧。 从此&#xff0c;无惧AI&#xff0c;无惧编程。 AI之路就在脚下。 AI&#xff0c;在我理解&#xff0c;就是让机器变得更加智能&#…...

Day25 235二叉搜索树的公共祖先 701二叉搜索树插入 450二叉搜索树删除

235 二叉搜索树的最近公共祖先 如果利用普通二叉树的方法&#xff0c;就是利用后序遍历回溯从低向上搜索&#xff0c;遇到左子树有p&#xff0c;右子树有q&#xff0c;那么当前结点就是最近公共祖先。本题是二叉搜索树&#xff0c;所以说是有序的&#xff0c;一定能够简化上面…...

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 七种事务传播性介绍

作者&#xff1a;vivo 互联网服务器团队 - Zhou Shaobin 本文主要介绍了Spring事务传播性的相关知识。 Spring中定义了7种事务传播性&#xff1a; PROPAGATION_REQUIRED PROPAGATION_SUPPORTS PROPAGATION_MANDATORY PROPAGATION_REQUIRES_NEW PROPAGATION_NOT_SUPPORTED…...

Count the Colors ZOJ - 1610

题目链接 题意&#xff1a; 给定n个区间[ l, r ]和颜色c, 每次给[l, r]涂上c这个颜色. 后面的涂色会覆盖之前的涂色. 最后要求输出区间[0, 8000]中每种颜色及其出现的次数, 如果该颜色没有出现过则不输出. 思路&#xff1a;典型的线段树区间染色问题&#xff0c;一般这种题…...

MATLAB点云处理总目录

一、点云滤波 原始点云包含过多噪点和冗余点&#xff0c;滤波和采样往往是点云预处理的必要步骤 1.滤波 重复点去除 NAN或INF无效点去除 自定义半径滤波 2.采样 基于空间格网的点云抽稀 随机下采样 均匀体素下采样 非均匀体素下采样 二、邻近搜索 如何组织点云快速获取当前…...

C语言逗号表达式如何计算

在 C 语言中&#xff0c;逗号表达式是一种特殊的表达式形式&#xff0c;它由逗号分隔的多个表达式组成。 逗号表达式的计算过程如下&#xff1a;1、从左到右依次计算每个表达式的值。2、最终返回的值是最右边表达式的值。3、逗号表达式的求值过程是顺序执行的&#xff0c;不会…...

Ubuntu 本地部署 ChatGPT-Next-Web

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

小程序商城搭建:快速入门指南

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

c# windows10大小端试

测试代码&#xff1a; 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大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…...

How to view the high-tech zone atmospheric project

How to view the high-tech zone atmospheric project 问题与建议登录界面没有验证码部分页面加载时间过长联动型下拉列表框点击反应迟钝页面缺乏导航没有采用https协议没有完成域名实名认证左侧菜单区不能收缩大屏区域功能图层不能完全隐藏部分页面表单控件没有文案提示其功能…...

sqlalchemy 中的缓存机制解释

SQLAlchemy 的缓存机制主要涉及两个层面&#xff1a;会话&#xff08;Session&#xff09;缓存和查询缓存。这两种缓存机制对于提升应用性能和数据一致性都非常重要。下面详细解释这两种缓存机制&#xff1a; 1. 会话&#xff08;Session&#xff09;缓存 会话缓存是 SQLAlch…...

网络安全B模块(笔记详解)- 漏洞扫描与利用

漏洞扫描与利用 1.通过Kali对服务器场景server2003以半开放式不进行ping的扫描方式并配合a,要求扫描信息输出格式为xml文件格式,从生成扫描结果获取局域网(例如172.16.101.0/24)中存活靶机,以xml格式向指定文件输出信息(使用工具Nmap,使用必须要使用的参数),并将该操…...

【C语言】指针——从底层原理到应用

C语言指针-从底层原理到花式技巧&#xff0c;用图文和代码帮你讲解透彻 目录 一、前言二、变量与指针的本质 1. 内存地址2. 32位与64位系统3. 变量4. 指针变量5. 操作指针变量 5.1 指针变量自身的值5.2 获取指针变量所指向的数据5.3 以什么样的数据类型来使用/解释指针变量所指…...

想了解步进伺服的朋友可以了解下这个方案

TMC4361A 是一款小型化、高性能的驱动步进电机的运动控制器。实用于很多的斜坡轮廓的应用&#xff0c;特别是速度快、限制过冲的运动场合。用户根据自己的要求实现 S 形或 sixPoint™六点式速度轮廓配置及闭环或开环的操作、动态修改运动参数。TMC4361A 包含 SPI接口、Step/Dir…...

航天航空线束工艺3D虚拟展馆支持多人异地参观漫游

为了满足汽车线束企业员工工作需要&#xff0c;让新老员工了解到更先进、规范的线束工艺设计技术&#xff0c;华锐视点基于VR虚拟仿真、web3d开发和图形图像技术制作了一款汽车线束工艺设计VR虚拟仿真模拟展示系统。 汽车线束工艺设计VR虚拟仿真模拟展示系统共分为pc电脑端和VR…...

JAVA面向对象基础-容器

一、泛型 我们可以在类的声明处增加泛型列表&#xff0c;如&#xff1a;<T,E,V>。 此处&#xff0c;字符可以是任何标识符&#xff0c;一般采用这3个字母。 【示例9-1】泛型类的声明 1 2 3 4 5 6 7 8 9 10 class MyCollection<E> {// E:表示泛型; Object[] o…...

2022年山东省职业院校技能大赛高职组信息安全管理与评估—开发测试服务器解析

任务5:开发测试服务器 目录 任务5:开发测试服务器 解题方法:...

2024年我国网络安全发展形势展望

2023年&#xff0c;我国网络安全政策法规陆续出台&#xff0c;网络安全与数据安全产业发展势头强劲&#xff0c;网络安全形势整体向好。展望2024年&#xff0c;世界各国在网络空间中的竞争将变得愈发激烈&#xff0c;我国网络安全领域的法律法规将不断完善&#xff0c;数据安全…...

如何使用 NFTScan NFT API 在 PlatON 网络上开发 Web3 应用

PlatON 是由万向区块链和矩阵元主导开发的面向下一代的全球计算架构&#xff0c;创新性的采用元计算框架 Monad 和基于 Reload 覆盖网络的同构多链架构&#xff0c;其愿景是成为全球首个提供完备隐私保护能力的运营服务网络。它提供计算、存储、通讯服务&#xff0c;并提供算力…...

网站如何做淘宝推广/荆州网站seo

摘要 按照产品在电磁兼容设计时所采取的各项措施的重要性为先后&#xff0c;分为若干层次进行设计&#xff0c;并加以综合分析进行适当调整直到完善&#xff0c;这就是本文提出的” 电磁兼容分层与综合设计法”。可以做到电磁兼容试验一次成功。 人们在研发新产品时&#xff0…...

常宁网站建设/百度热门排行榜

–ACC建模大数据用于精简用例的实践 作者&#xff1a;emilyxlchen生活的智慧&#xff0c;有时不在于多&#xff0c;而在于少。同理适用于测试用例的管理中。 一&#xff0e;热身活动&#xff1a;数一数你的产品总用例 随着互联网时代节奏的日益加快&#xff0c;许多产品都会…...

网站路径问题/网络营销价格策略有哪些

潭桥相望翡翠圆盘水晶珠&#xff0c;小桥微倾波上浮。玉树两行亭亭立&#xff0c;碧水一带引城出。楼台历历巍峨远&#xff0c;钓者悠悠心且闲。禅门静修四季景&#xff0c;堂前三步有诗篇。 Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId1699789...

小程序怎么做电影网站/企业营销网站建设系统

应用场景&#xff1a; 当列表数据太多时&#xff0c;就会进行分段查询&#xff0c;这就有了查看更多 小编在刚刚开始做的时候也是费了很大的劲&#xff0c;想了三种方案&#xff0c;这就不细说了&#xff0c;来说下最简单的方案 PHP代码&#xff1a; .....其实PHP是不需要处理什…...

网页设计公司兴田德润在哪里/seo网站优化培训公司

插入 insert into 表名 (列名...) values(值...); 1. 给表中的所有字段添加数据&#xff0c;可以不写前面的字段名称。 2. 只给表的某几个字段赋值&#xff0c;则需要制定字段名。 3. 在 values 中列出的数据位置必须与被加入的列位置相对应。 4. 数据类型&#xff0c;大小等…...

黄色网站目录推存/seo培训机构哪家好

温故&#xff1a; 在《FTP的两种登录方式》一文中已经对FTP的原理做了简单的介绍&#xff0c;主要讲了授权登录和匿名登录的区别&#xff0c;而且在文章的最后还特意对“匿名FTP”进行了拓展&#xff0c;有兴趣的建议看看。 知新&#xff1a; 今天相对FTP的其他小知识做一个补…...