物联网实战--平台篇之(十二)设备管理前端

目录

一、界面演示

二、设备列表

三、抖动单元格

四、设备模型

五、设备编辑


本项目的交流QQ群:701889554

物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html

物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.html

一、界面演示

设备管理演示

二、设备列表

        参考了几个现有的智能家居相关的APP,他们的设备管理模式基本差不多,都是这种单元格的方式,在QML里,就是GridView组件了,以下是设备列表相关的前端QML代码:

import QtQuick 2.7
import QtQuick.Controls 2.0
import "../base"

Rectangle
{
    property var groupName: ""

    id:id_rootRect
    height: parent.height
    width: parent.width-20
    color: "transparent"
    anchors.horizontalCenter: parent.horizontalCenter
    DevDelDialog//设备删除对话框
    {
        id:id_devDelDialog
        onSiqOkClicked: 
        {
            var dev_list=[]
            var ptr=0
            for(var i=0; i<id_cellModel.count; i++)
            {
                if(id_cellModel.get(i).select_state)//选中
                {
                    dev_list[ptr++]=id_cellModel.get(i).dev_sn
                }
            }
            theCenterMan.requestDelDevice(dev_list)
            funClose()
        }
    }

    DevRenameDialog//设备重命名对话框
    {
        id:id_devRenameDialog
        
        onSiqOkClicked: 
        {
            theCenterMan.requestRenameDevice(devSn, text)
            funClose()
        }
        
    } 
    
    GridView {
        id:id_gridView
        property int dragItemIndex: -1
        property var dragActive: false
        property int selectCnts: 0
        property var sortFlag: false
        anchors.fill: parent
        clip: true
        cacheBuffer: 10000
        implicitWidth: 150
        implicitHeight: 150
        cellWidth: width*0.5
        cellHeight: cellWidth*0.8
        
        move:Transition {
            NumberAnimation { properties: "x,y"; duration: 200 }
        }
        moveDisplaced:Transition {
            NumberAnimation { properties: "x,y"; duration: 200 }
        }
        
        model: ListModel{
            id:id_cellModel
        }
        delegate: Rectangle{//单元格矩形
            id:id_cellRect
//            property var selectState: false
            color: "transparent"
//            border.color: "blue"
//            border.width: 1
            width: id_gridView.cellWidth
            height: id_gridView.cellHeight
            
            Rectangle //拖动矩形
            {
                id:id_dragRect
                radius: 12
                width: id_cellRect.width-15
                height:id_cellRect.height-15
                anchors.centerIn:id_cellRect
                color: id_moveMouseArea.drag.active ? "transparent" : "white"
                
                onParentChanged: 
                {
                    if(parent!=null)
                    {
                        theCenterMan.showSimpleView(dev_sn, id_dragRect)
                    }         
                } 
                
                Rectangle{  //勾选框
                    id:id_selectRect
                    width: 24
                    height: width
                    radius: width/2
                    border.width: 1
                    border.color: "#D0D0D0"
                    visible: id_gridView.dragActive
                    anchors
                    {
                        top:parent.top
                        topMargin:15
                        right:parent.right
                        rightMargin:15
                    }
                    Image {
                        id: id_selectImage
                        anchors.fill: parent
                        visible: select_state
                        mipmap: true
                        source: "qrc:/imagesRC/mainImages/check.png"
                    }
                }
                
                MouseArea
                {
                    id:id_moveMouseArea
                    anchors.fill: parent
//                    drag.target: id_dragRect
                    drag.axis: Drag.YAxis | Drag.XAxis
                    drag.onActiveChanged: {
                        if (id_moveMouseArea.drag.active) 
                        {
                            id_gridView.dragItemIndex = index;
                                console.log("drag index=", index)
                        }
                        id_dragRect.Drag.drop();
                    }
                    onClicked: 
                    {
                        if(id_gridView.dragActive)
                        {
                            select_state=!select_state
                            if(select_state)
                                id_gridView.selectCnts++
                            else
                                id_gridView.selectCnts--
//                            console.log("selectCnts=", id_gridView.selectCnts)
                        }
                    }
                    onPressAndHold: 
                    {
                        id_gridView.dragActive=true
                        select_state=true
                        id_gridView.selectCnts=1
                    }
                    onReleased: 
                    {
//                        drag.target=null
//                        id_gridView.dragActive=false
//                        id_dropAnimation.stop()
                    }
                }
                states: [
                    State {
                        when: id_dragRect.Drag.active
                        ParentChange {
                            target: id_dragRect
                            parent: id_rootRect
                        }
    
                        AnchorChanges {
                            target: id_dragRect
                            anchors.horizontalCenter: undefined
                            anchors.verticalCenter: undefined
                        }
                    }
                ]
                Drag.active: id_moveMouseArea.drag.active
                Drag.hotSpot.x: id_dragRect.width / 2
                Drag.hotSpot.y: id_dragRect.height / 2
                
            }
            DropArea {  //拖拽
            id: dropArea
            anchors.fill: parent
            onDropped:{
                console.log("onDropped")
                var other_index = id_gridView.indexAt(id_moveMouseArea.mouseX + id_cellRect.x, id_moveMouseArea.mouseY + id_cellRect.y);
                console.log("other_index:",other_index,"id_gridView.dragItemIndex:",id_gridView.dragItemIndex);
                if(other_index!==id_gridView.dragItemIndex && other_index>=0)
                {
                    id_cellModel.move(id_gridView.dragItemIndex,other_index, 1);
                    id_gridView.sortFlag=true//有排序动作
                }
            }
            
            Rectangle {
                    id: dropRectangle
    
                    anchors.centerIn:parent
                    width: id_dragRect.width
                    height: id_dragRect.height
                    color: "transparent"
                    radius: 12
                    states: [
                        State {
                            when: dropArea.containsDrag
                            PropertyChanges {
                                 target: dropRectangle
                                 color: "lightsteelblue"
                                 opacity:0.3
                            }
                        }
                    ]
                }//end Rectangle
    
            }//end drop
            
            PropertyAnimation { //抖动
                id:id_dropAnimation
                target: id_dragRect
                properties: "rotation"
                from:-1.5
                to:1.5
                duration: 300
                easing.type: Easing.InOutExpo
                loops: 300 //循环次数
                onStopped: 
                {
                    target["rotation"] = 0 //显示归位
                }
            }
            Timer{
                interval: Math.random()*500; running: true; repeat: true
                onTriggered: 
                {
                    if(id_gridView.dragActive)
                    {
                        if(id_dropAnimation.stopped)
                        {
                            id_dropAnimation.start()
                            id_moveMouseArea.drag.target=id_dragRect         
                        }
                    }
                    else
                    {
                        if(id_dropAnimation.started)
                        {
                            id_dropAnimation.stop()
                            id_moveMouseArea.drag.target=null
                            select_state=false
                            id_gridView.selectCnts=0
                        }
                    }
                }
            }
    
        }//end delegate
        
    }//end GridView
    
    Rectangle  //设置栏
    {
        id:id_setRect
        
        width: parent.parent.width
        height: 60
        anchors
        {
            horizontalCenter:parent.horizontalCenter
            bottom:id_gridView.bottom
        }
        MouseArea{
            anchors.fill: parent //接收鼠标事件,避免选择背后的单元格
        }
        color: "#606060"
//        opacity: 0.5
        visible: id_gridView.dragActive
        
        Row
        {
            height: id_setRect.height
            width: id_setRect.width*0.9
            anchors
            {
                top:parent.top
                topMargin:5
                horizontalCenter:id_setRect.horizontalCenter
            }
            spacing: (width-30*4)/3
            Repeater
            {
                model: ListModel{
                    id:id_setModel
                }
                Rectangle{
                    property var maskFlag: index===0 && id_gridView.selectCnts!==1
                    height: 30
                    width: height
                    radius: width/2
                    color:  maskFlag ? "#808080" : "white"
                    ImageButton01 {
                        anchors.centerIn: parent
                        width: parent.width*0.7
                        height: width
                        mipmap: true 
                        source: img_src
                        onSiqClickedLeft: 
                        {
//                            console.log("clicked index=", index)
                            switch(index)
                            {
                                case 0: //修改名称
                                    if(id_gridView.selectCnts===1)
                                    {
                                        for(var i=0; i<id_cellModel.count; i++)
                                        {
                                            if(id_cellModel.get(i).select_state)//选中
                                            {
                                                id_devRenameDialog.devSn=id_cellModel.get(i).dev_sn
                                                id_devRenameDialog.oldName=theCenterMan.takeWorkDeviceName(id_devRenameDialog.devSn)//旧名称
                                                id_devRenameDialog.funOpen(id_devRenameDialog.oldName)
                                                break
                                            }
                                        }         
                                    }
                                    break
                                case 1: //移动设备
                                    id_devMoveDialog.open()
                                    var dev_list=[]
                                    var ptr=0
                                    for(i=0; i<id_cellModel.count; i++)
                                    {
                                        if(id_cellModel.get(i).select_state)//选中
                                        {
                                            dev_list[ptr++]=id_cellModel.get(i).dev_sn
                                        }
                                    }
                                    id_devMoveDialog.srcGroupName=groupName
                                    id_devMoveDialog.moveDevList=dev_list
                                    break
                                case 2: //删除设备
                                    id_devDelDialog.funOpen()
                                    break                                    
                                case 3:  //完成
                                    id_gridView.dragActive=false;
                                    if(id_gridView.sortFlag==true)//有排序动作
                                    {
                                        id_gridView.sortFlag=false
                                        dev_list=[]
                                        for(i=0; i<id_cellModel.count; i++)
                                        {
                                            dev_list[i]=id_cellModel.get(i).dev_sn
                                        }
                                        theCenterMan.requestSortDevice(groupName, dev_list)//排序
                                    }
                                    break
                            }
                        }
                    }
                    Text{
                        height: 25
                        anchors
                        {
                            horizontalCenter:parent.horizontalCenter
                            top:parent.bottom
                            topMargin:3
                        }
                        text: name
                        font.pointSize: 10
                        font.family: "宋体"
                        color:  maskFlag ? "#808080" : "white"
                    }
                }

            }
        }
        

        
    }
    
    
    Connections
    {
        target: theCenterMan
        onSiqAddDevice2Group:
        {
            if(group_name===groupName)
            {
                id_cellModel.append({"dev_sn":dev_sn, "select_state":false})
            }
        }
        onSiqDelDevice:
        {
            for(var i=0; i<id_cellModel.count; i++)
            {
                if(dev_sn===id_cellModel.get(i).dev_sn)
                {
                    id_cellModel.remove(i)
                    break
                }
            }
            if(flag>0)  //删除完成
            {
                var dev_list=[]
                var ptr=0
                for(i=0; i<id_cellModel.count; i++)
                {
                    dev_list[ptr++]=id_cellModel.get(i).dev_sn
                }
                theCenterMan.requestSortDevice(groupName, dev_list)//重新排序
            }
        }
        onSiqClearDevice:
        {
            if(group_name===groupName)
            {
                id_cellModel.clear()
            }
        }
    }
    
    Component.onCompleted: 
    {

        var img_src="qrc:/imagesRC/mainImages/home/rename.png"
        var name="修改名称"
        id_setModel.append({"img_src":img_src, "name":name})
        img_src="qrc:/imagesRC/mainImages/home/move.png"
        name="移动设备"
        id_setModel.append({"img_src":img_src, "name":name})  
        img_src="qrc:/imagesRC/mainImages/home/del02.png"
        name="删除设备"
        id_setModel.append({"img_src":img_src, "name":name})  
        img_src="qrc:/imagesRC/mainImages/home/finish.png"
        name="完成"
        id_setModel.append({"img_src":img_src, "name":name})  
        
    }
    
}

        在GridView里的重点其实就是拖拽排序功能了,跟之前的分组排序类似的,只不过网格拖拽复杂点,首先方向是X和Y两个方向;然后是抖动效果,在长按某个设备单元格后整体就会抖动起来,让用户直观地感受到是在编辑状态;最后是选中效果,用户选中后就会增加一个打勾按钮,本质就是图片显示条件设置了。

三、抖动单元格

        抖动使用的是动画组件,其中需要改变的对象是拖拽矩形,改变的属性是角度,范围从-1.5~1.5角度,如果停止后角度重置为0。在这里我们加个定时器用来管理所有单元格的抖动状态,在有设备被长按激活拖拽后,网格里所有的设备都要抖动起来,在定时器里启动;如果退出编辑去激活后,同样是在定时器内检测停止。

           PropertyAnimation { //抖动
                id:id_dropAnimation
                target: id_dragRect
                properties: "rotation"
                from:-1.5
                to:1.5
                duration: 300
                easing.type: Easing.InOutExpo
                loops: 300 //循环次数
                onStopped: 
                {
                    target["rotation"] = 0 //显示归位
                }
            }
            Timer{
                interval: Math.random()*500; running: true; repeat: true
                onTriggered: 
                {
                    if(id_gridView.dragActive)
                    {
                        if(id_dropAnimation.stopped)
                        {
                            id_dropAnimation.start()
                            id_moveMouseArea.drag.target=id_dragRect         
                        }
                    }
                    else
                    {
                        if(id_dropAnimation.started)
                        {
                            id_dropAnimation.stop()
                            id_moveMouseArea.drag.target=null
                            select_state=false
                            id_gridView.selectCnts=0
                        }
                    }
                }
            }

四、设备模型

        设备模型是我们后续开发新硬件产品所需要对应增加的内容,在其它平台上,很多称之为物模型,一般用json语句来描述设备的属性、状态和功能,这种模式的特点是通用性比较强,缺点是性能损耗大,深度定制使用体验不佳,所以只能定义一些较为简单的设备模型,复杂的调试起来很麻烦。那么,我们这边的思想还是以代码驱动为核心,物模型后端逻辑直接用C/C++实现,前端界面用QML实现,配套使用,下面举例说明。

        

        如上图所示,modelCpp存放的是物模型后端代码,modelQml存放的是物模型前端代码,由于各个物模型有一定相似性,所以都会定义一个基本的模型,具体设备模型再继承于这个基础模型,在这里我们以后面要实现的净化器为例,定义型号为AP01,那么他的ModelAp01,继承于BaseModel,具体的后面完善净化器项目的时候再说明。

        同样的,前端代码也是这种模式,SimpleAp01.qml继承于BaseSimpleView,带Simple说明是简易模型,就是每个单元格内显示的内容,对于每个物模型有两个界面,一个是这里所说的简易界面,另一个是详情界面,就是之前净化器项目那个可以具体控制操作的界面。

        对于模型的显示也是一个需要技巧的地方,首先要知道,每个界面都需要有一个父组件/窗口,这样才能显示,对于设备模型前端来讲,它的父窗口其实就是那个可以被拖拽的单元格了,所以我们要显示模型的时候,就是将这个单元格地址传到模型里去,然后模型内部自己主动显示在单元格上,下面通过代码了解这一流程。

        首先在网格单元格内,当单元格创建完成后,会触发onParentChanged信号,在这里就可以根据设备sn将单元格矩形最为父窗口,把指针传入模型后端。

        然后我们来看看控制中心的showSimpleView函数的内容,如下所示,就是根据dev_sn找到这个模型实例对象,然后调用模型的showSimple进行显示,注意,这里继续将父窗口指针继续传递。

        接下来是重头戏,如下图所示,是不是感觉似曾相识,跟主程序显示是一样的,每个模型内部都有一个QML显示引擎,通过这里的配置,就可以实现模型内容的前后端交互了,在这里有两个接口,theModelAp01和theCenterMan,其中通过theCenterMan可以调用CenterMan类内的相关功能。函数末尾就是加载SimpleAp01这个模型文件。

        到此为止,物模型并不能显示,因为上图中的父窗口指针只是保存在C++后端了,并没有跟前端的QML有什么关联,这就引出了最后一步,就是在具体的QML模型文件内调用takeModelParent(),将刚才保存在后端的父窗口指针赋值到当前模型的parent属性,这样就形成了闭环,完成了模型显示的功能。

五、设备编辑

        当用户长按某个单元格后,除了单元格会抖动起来以外,底部还会出现一个设置栏,目前定义的功能是修改名称、移动设备和删除设备,这里比较复杂的还是上一篇所写的后台管理,特别是移动设备功能;那么对于前端代码主要做个展示,具体内容自己阅读理解应该问题不大。

   Rectangle  //设置栏
    {
        id:id_setRect
        
        width: parent.parent.width
        height: 60
        anchors
        {
            horizontalCenter:parent.horizontalCenter
            bottom:id_gridView.bottom
        }
        MouseArea{
            anchors.fill: parent //接收鼠标事件,避免选择背后的单元格
        }
        color: "#606060"
//        opacity: 0.5
        visible: id_gridView.dragActive
        
        Row
        {
            height: id_setRect.height
            width: id_setRect.width*0.9
            anchors
            {
                top:parent.top
                topMargin:5
                horizontalCenter:id_setRect.horizontalCenter
            }
            spacing: (width-30*4)/3
            Repeater
            {
                model: ListModel{
                    id:id_setModel
                }
                Rectangle{
                    property var maskFlag: index===0 && id_gridView.selectCnts!==1
                    height: 30
                    width: height
                    radius: width/2
                    color:  maskFlag ? "#808080" : "white"
                    ImageButton01 {
                        anchors.centerIn: parent
                        width: parent.width*0.7
                        height: width
                        mipmap: true 
                        source: img_src
                        onSiqClickedLeft: 
                        {
//                            console.log("clicked index=", index)
                            switch(index)
                            {
                                case 0: //修改名称
                                    if(id_gridView.selectCnts===1)
                                    {
                                        for(var i=0; i<id_cellModel.count; i++)
                                        {
                                            if(id_cellModel.get(i).select_state)//选中
                                            {
                                                id_devRenameDialog.devSn=id_cellModel.get(i).dev_sn
                                                id_devRenameDialog.oldName=theCenterMan.takeWorkDeviceName(id_devRenameDialog.devSn)//旧名称
                                                id_devRenameDialog.funOpen(id_devRenameDialog.oldName)
                                                break
                                            }
                                        }         
                                    }
                                    break
                                case 1: //移动设备
                                    id_devMoveDialog.open()
                                    var dev_list=[]
                                    var ptr=0
                                    for(i=0; i<id_cellModel.count; i++)
                                    {
                                        if(id_cellModel.get(i).select_state)//选中
                                        {
                                            dev_list[ptr++]=id_cellModel.get(i).dev_sn
                                        }
                                    }
                                    id_devMoveDialog.srcGroupName=groupName
                                    id_devMoveDialog.moveDevList=dev_list
                                    break
                                case 2: //删除设备
                                    id_devDelDialog.funOpen()
                                    break                                    
                                case 3:  //完成
                                    id_gridView.dragActive=false;
                                    if(id_gridView.sortFlag==true)//有排序动作
                                    {
                                        id_gridView.sortFlag=false
                                        dev_list=[]
                                        for(i=0; i<id_cellModel.count; i++)
                                        {
                                            dev_list[i]=id_cellModel.get(i).dev_sn
                                        }
                                        theCenterMan.requestSortDevice(groupName, dev_list)//排序
                                    }
                                    break
                            }
                        }
                    }
                    Text{
                        height: 25
                        anchors
                        {
                            horizontalCenter:parent.horizontalCenter
                            top:parent.bottom
                            topMargin:3
                        }
                        text: name
                        font.pointSize: 10
                        font.family: "宋体"
                        color:  maskFlag ? "#808080" : "white"
                    }
                }

            }
        }
        

        
    }

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

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

相关文章

彩灯控制器设计 74ls160+ne555实现

一、选题背景 数字电子技术在我们生活中的应用非常之广泛,不论是在各个方面都会涉及到它,小到家用电器的自动控制,大到神舟九号和天空一号航天器的设计,都无可避免的要运用它。并且鉴于以理论推动实践及理论实践相结合为指导思想,特此用我们所学的理论知识来实践这次课程设…

Nginx编译安装,信号,升级nginx

编译安装nginx&#xff1a;前面博客有写编译安装过程 systemctl stop firewalld setenforce 0 mkdir /data cd /data wget http://nginx.org/download/nginx-1.18.0.tar.gz tar xf nginx-1.18.0.tar.gz cd nginx-1.18.0/ yum -y install make gcc pcre-devel openssl-devel …

数据结构与算法03-散列表(哈希表)

介绍 散列表&#xff08;Hash table&#xff0c;也叫哈希表&#xff09;&#xff0c;是根据键&#xff08;Key&#xff09;而直接访问在存储器存储位置的数据结构。也就是说&#xff0c;它通过计算出一个键值的函数&#xff0c;将所需查询的数据映射到表中一个位置来让人访问&…

项目质量管理

目录 1.概述 2.三个关键过程 2.1.规划质量管理&#xff08;Plan Quality Management&#xff09; 2.2.管理质量&#xff08;Manage Quality&#xff09; 2.3.控制质量&#xff08;Control Quality&#xff09; 3.应用场景 3.1.十个应用场景 3.2.产品设计与开发 4.小结…

【自动驾驶技术】自动驾驶汽车AI芯片汇总——地平线篇

0. 前言 按照国际惯例&#xff0c;首先声明&#xff1a;本文只是我自己学习的理解&#xff0c;虽然参考了他人的宝贵见解及成果&#xff0c;但是内容可能存在不准确的地方。如果发现文中错误&#xff0c;希望批评指正&#xff0c;共同进步。 本篇文章是这个系列的第二篇&#x…

微信小程序毕业设计-书橱系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

[C][栈帧]详细讲解

目录 1.栈帧1.进程地址空间2.栈帧说明 2.认识相关寄存器3.认识相关汇编命令4.过程理解5.栈帧总结6.补充 1.栈帧 1.进程地址空间 .进程地址空间 2.栈帧说明 调用函数&#xff0c;形成栈帧函数返回&#xff0c;释放栈帧局部变量是存放在栈区上的栈区内存的使用习惯是&#xff…

数据结构之实现“通讯录”

大家先赞后看&#xff0c;养成好习惯 你们的点赞和关注还有收藏就是我的动力&#xff01;&#xff01;&#xff01; 目录 前言 一、通讯录文件的创建和联系人结构体定义 1.1 文件创建 1.2 联系人结构体定义 二、通讯录的功能实现 2.1通讯录初始化 2.2通讯录销毁 2.3添…

使用手机小程序给证件照换底色

临时遇到一个需求&#xff0c;需要给证件照换底色。原始图像如下 最终需要换成红底的。 本次使用一款小程序&#xff02;泰世茂证件照&#xff02;&#xff0c;打开该小程序&#xff0c;如下图所示 单击开始制作&#xff0c;然后选择二寸红底&#xff0c;如下图所示 然后单击相…

【AIGC时代】探索AIGC的无限可能:释放你的创意,定制你的视觉世界

前言 在数字时代的浪潮中&#xff0c;我们的视觉体验正在经历前所未有的变革。随着科技的飞速发展&#xff0c;我们不再满足于传统的图片制作方式&#xff0c;而是渴望拥有更具创意、更富个性的视觉呈现。在这样的背景下&#xff0c;AIGC&#xff08;人工智能生成内容&#xf…

IF:83.5!一作兼通讯,​Nature系列综述:可以吃的机器人!

在当今科技与生物工程快速融合的时代&#xff0c;传统领域之间的界限正在逐渐模糊&#xff0c;创造了许多前所未有的创新机会。机器人设计与食品加工这两个看似无关的研究领域&#xff0c;正在通过材料特性、制造工艺和功能的交叉融合&#xff0c;展现出巨大的潜力。 可食用机器…

Flutter 验证码输入框

前言&#xff1a; 验证码输入框很常见&#xff1a;处理不好 bug也会比较多 想实现方法很多&#xff0c;这里列举一种完美方式&#xff0c;完美兼容 软键盘粘贴方式 效果如下&#xff1a; 之前使用 uniapp 的方式实现过一次 两种方式&#xff08;原理相同&#xff09;&#xff1…

【TB作品】MSP430F5529,单片机,电子秒表,秒表

硬件 MSP430F5529开发板7针0.96寸OLED /* OLED引脚分配 绿色板子DO(SCLK)------P4.3D1(DATA)------P4.0RES-----------P3.7DC------------P8.2CS------------P8.1 */ 程序功能 该程序是一个用C语言编写的&#xff0c;用于msp430f5529微控制器上的简单电子秒表应用。它使用…

多源 BFS 详解

目录 一、多源与单源的区别 二、例题练习 2.1 例题1&#xff1a;01 矩阵 2.2 例题2&#xff1a;飞地的数量 2.3 例题3&#xff1a;地图中的最高点 2.4 例题4&#xff1a;地图分析 一、多源与单源的区别 单源最短路问题如何解决已经在上篇博客给出BFS 解决最短路问题&am…

Qt | Qt 资源简介(rcc、qmake)

1、资源系统是一种独立于平台的机制,用于在应用程序的可执行文件中存储二进制文件(前面所讨论的数据都存储在外部设备中)。若应用程序始终需要一组特定的文件(比如图标),则非常有用。 2、资源系统基于 qmake,rcc(Qt 的资源编译器,用于把资源转换为 C++代码)和 QFile …

Java扩展机制:SPI与Spring.factories详解

一、SPI SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。 整体机制图如下: Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制。 系统设计的各个抽象,往往有很多不…

【车载开发系列】汽车开发常用工具说明

【车载开发系列】汽车开发常用工具说明 【车载开发系列】汽车开发常用工具说明 【车载开发系列】汽车开发常用工具说明一. CANbedded二. Davinci Configurator Pro三. Davinci Developer-AUTOSAR软件组件设计工具四. MICROSAR五. MICROSAR OS六. CANdelaStudio七. Volcano VSB八…

css动态导航栏鼠标悬停特效

charset "utf-8"; /*科e互联特效基本框架CSS*/ body, ul, dl, dd, dt, ol, li, p, h1, h2, h3, h4, h5, h6, textarea, form, select, fieldset, table, td, div, input {margin:0;padding:0;-webkit-text-size-adjust: none} h1, h2, h3, h4, h5, h6{font-size:12px…

Nodejs-- 网络编程

网络编程 构建tcp服务 TCP tcp全名为传输控制协议。再osi模型中属于传输层协议。 tcp是面向连接的协议&#xff0c;在传输之前需要形成三次握手形成会话 只有会话形成了&#xff0c;服务端和客户端才能想发送数据&#xff0c;在创建会话的过程中&#xff0c;服务端和客户…

【计算机毕业设计】353微信小程序零食批发交易管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…