QtQuick桌面应用开发指导 4)动态管理Note对象_B 5)外观加强 6)更多改进

4.2.2 Stateless(状态无关的)JavaScript库

为了让开发轻松点, 使用一个JavaScript接口来和数据库交互是个好主意, 它在QML中提供了方便的方法;

在QtCreator中创建一个新的JavaScript文件 noteDB.js, 保证选择了 State Library选项; 这样使得noteDB.js用起来像一个库, 提供了stateless的helper方法; 这样,在每个QML组件 import noteDB.js以及使用它的时候, 就只有一份实例被加载和使用; 这也保证了只有一个全局变量用来存储数据库实例: _db;

Note Non-stateless(非状态无关的)JavaScript文件在导入一个QML组件的时候很有用, 可以对那个组件执行操作, 所有的变量只有在那份context(上下文)中有效; 每次import都会创建一个独立的JavaScript文件的实例;

noteDB.js应该提供下面的功能:

- 打开/创建一个本地数据库实例

- 创建必须的数据库table(表格)

- 从数据库读取notes

- 删除所有的notes

接下来会看到 关于noteDB.js中的方法如何被实现的许多的细节--读取, 存储note item到数据库的实现; 先考虑下面的方法实现:

- function openDB() - 如果数据库不存在, 就创建一个, 存在就打开它;

- function createNoteTable() - 如果note table不存在就创建note table; 这个方法只会在 openDB()中调用;

- function clearNoteTable() - 从note table中移除所有的行(row);

- readNotesFromPage(markerId) - 这个helper方法读取所有和特定markerId相关联的note, 返回一个dictionary(字典)类型的数据;

- function saveNotes(noteItems, markerId) - 用来在数据库中保存note item; noteItem参数代表一个note item的list(列表), markerId代表note item隶属的那个相应的page;

Note 所有这些JavaScript方法使用Qt Quick Local Storage API来获取数据库, 声明语句(statement) import QtQuick.LocalStorage 2.0 as Sql, 要写在 noteDB.js的开始;

4.2.3 读取和存储Note

实现了noteDB.js之后, 可以使用方法来读取和存储note了;

一个好的做法是在main.qml文件中, 在初始化的时候或打开数据库连接的时候才去调用; 这样我们可以使用定义在noteDB.js中的JavaScript方法而不会重新初始化(reinitializing)数据库;

在main.qml里面导入noteDB.js 和 QtQuick.LocalStorage 2.0, 有个问题是什么时候调用 openDB()方法; QML提供了helpful attached signal: onCompleted()和 onDestruction(), 会在Component被完全加载完全销毁的时候各自emit(发送);

// main.qml


1

2

3

4

5

6

7

8

9

import
QtQuick 2.0

import "noteDB.js" as
NoteDB

Item
{

    //
this signal is emitted upon component loading completion

    Component.onCompleted:
{

        NoteDB.openDB()

    }

//...

下面是openDB方法实现, 它调用 openDatabaseSync()方法来创建数据库, 之后调用 createNoteTable()方法来创建note表;

//noteDB.js


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

.pragma
library

.import
QtQuick.LocalStorage 2.0 as Sql

//
declaring a global variable for storing the database instance

var _db

function openDB()
{

    print("noteDB.createDB()")

    _db
= openDatabaseSync(
"StickyNotesDB","1.0",

            "The
stickynotes Database"
,
1000000);

    createNoteTable();

}

function createNoteTable()
{

    print("noteDB.createTable()")

    _db.transaction( function(tx)
{

        tx.executeSql(

            "CREATE
TABLE IF NOT EXISTS note

            (noteId
INTEGER PRIMARY KEY AUTOINCREMENT,

            x
INTEGER,

            y
INTEGER,

            noteText
TEXT,

            markerId
TEXT)"
)

    })

}

在main.qml里面, 初始化了数据库, 安全地开始从Page组件中加载Note item; 上面我们提到了 readNotesFromPage(markerId)方法, 返回一个data array(数组)list (参照script world--脚本世界里的dictionary), 每个数组代表数据库中的一行--note的数据;

//noteDB.js


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

//...

function readNotesFromPage(markerId)
{

    print("noteDB.readNotesFromPage()
"
 +
markerId)

    var noteItems
= {}

    _db.readTransaction( function(tx)
{

        var rs
= tx.executeSql(

            "SELECT
FROM note WHERE markerId=?

            ORDER
BY markerid DESC"
,
[markerId] );

        var item

        for (var i=0;
i< rs.rows.length; i++) {

            item
= rs.rows.item(i)

            noteItems[item.noteId]
= item;

        }

    })

    return noteItems

}

Page组件会读取note然后创建相应的QML note对象;

// Page.qml


1

2

3

4

5

6

7

8

9

10

11

//...

//
when the component is loaded, call the loadNotes()

//
function to load notes from the database

Component.onCompleted:
loadNotes()

//
a Javascript helper function that reads the note data from database

function loadNotes()
{

    var noteItems
= NoteDB.readNotesFromPage(markerId)

    for (var in noteItems)
{

        newNoteObject(noteItems[i])

    }

}

我们可以看到 newNoteObject()方法在之前的Page.qml定义, 它得到一个data数组作为参数, 实际上就是 x, y, noteText, markerId和 noteId属性的值;

Note 注意note表的name域(field)和Note组件的属性一样; 这可以帮助我们把table行的数据作为参数传递, 创建note QML对象;

现在我们实现了从数据库加载Note item的方法, 下一个逻辑步骤是实现一个将note存储到DB中的方法; PagePanel组件是负责创建Page item的, 因此它应该可以从每张page上读取note, 然后调用 saveNote() JS方法来存储note;

//noteDB.js


1

2

3

4

5

6

7

8

9

10

11

12

//...

function saveNotes(noteItems,
markerId) {

    for (var i=0;
i<noteItems.length; ++i) {

        var noteItem
= noteItems[i]

        _db.transaction( function(tx)
{

            tx.executeSql(

            "INSERT
INTO note (markerId, x, y, noteText)

            VALUES(?,?,?,?)",

            [markerId,
noteItem.x, noteItem.y, noteItem.noteText]);

        })

    }

}

首先我们定义一个属性alias可以将Note item暴露出来, 这些item是作为在Page组件中container的children而创建的;

// Page.qml


1

2

3

4

5

//...

//
this property is used by the PagePanel component

//
for retrieving all the notes of a page and storing

//
them in the Database.

property
alias notes: container.children

在PagePanel中实现在DB中保存note的功能;

// PagePanel.qml


1

2

3

4

5

6

7

8

9

10

11

//...

    Component.onDestruction:
saveNotesToDB()

    //
a JavaScript function that saves all notes from the pages

    function saveNotesToDB()
{

        //
clearing the DB table before populating with new data

        NoteDB.clearNoteTable();

        //
storing notes for each individual page

        NoteDB.saveNotes(personalpage.notes,
personalpage.markerId)

        NoteDB.saveNotes(funpage.notes,
funpage.markerId)

        NoteDB.saveNotes(workpage.notes,
workpage.markerId)

    }

为了减少代码复杂度, 我们在保存note之前清楚DB中所有的数据; 这样可以不用谢代码来更新现存的Note item;

在结束本章前, 用户可创建和删除note, 程序也可以自动保存和加载note;

下一步

下一章介绍一些漂亮的动画, 以及实现的步骤和技巧;

---4End---

CHAPTER5 外观加强

NoteApp的UI可以看作按照功能和用户交互实现的; 其实还有很大的进步空间, 让UI更吸引用户; QML设计成一种声明式语言, 记得用动画和UI的流畅过度;

这一章会一步步实现动画, 让NoteApp感觉更优美(fluid); QML提供了一组QML类型以各种方式实现动画; 这一章会介绍一些新的类型, 在QML组件中使用它们, 让UI更加流畅;

总体上, 本章覆盖下面几点:

- 介绍animation(动画)和transition(过渡)效果;

- 新的QML类型: Behavior, Transition, 各种Animation元素;

- 使用各种动画强化NoteApp的QML组件;

5.1 NoteToolbar动画

我们来看看如何改进Note组件, 添加一些基于用户交互的行为; Note有一个toolbar, 可以用Delete tool删除笔记; toolbar是用来按下鼠标四处拖拽note用的;

一个改进是可以让Delete tool只有在需要的时候可见; 例如, 在toolbar上悬停(hover)的时候让Delete工具可见, 使用 fade-in/fade-out(渐入渐出)效果更漂亮;

Note opacity属性的值是从parent到child item传播的(propagated); [属性继承]

Behavior类型允许我们定义一个基于item的属性变化的行为;

// NoteToolbar.qml


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

//...   

    MouseArea
{

        id:
mousearea

        anchors.fill:
parent

        //
setting hoverEnabled property to true

        //
in order for the MouseArea to be able to get

        //
hover events

        hoverEnabled: true

    }

    //
using a Row element for laying out tool

    //
items to be added when using the NoteToolbar

    Row
{

        id:
layout

        layoutDirection:
Qt.RightToLeft

        anchors
{

            verticalCenter:
parent.verticalCenter;

            left:
parent.left;

            right:
parent.right

            leftMargin:
15;

            rightMargin:
15

        }

        spacing:
20

        //
the opacity depends if the mousearea

        //
has the cursor of the mouse.

        opacity:
mousearea.containsMouse ? 1 : 0

        //
using the behavior element to specify the

        //
behavior of the layout element

        //
when on the opacity changes.

        Behavior
on opacity {

            //
using NumberAnimation to animate

            //
the opacity value in a duration of 350 ms

            NumberAnimation
{ duration: 350 }

        }

    }

//...

上面代码可以看到, 我们启用MouseArea的hoverEnabled属性, 接收鼠标悬停事件; 之后, 我们可以把Row类型的opacity切换到0, 如果MouseArea类型没有悬停(hovered)就设为1; MouseArea的containsMouse属性用来决定opacity的值;

这样Behavior类型在Row中被创建出来, 基于opacity属性而定义它的行为; 当opacity改变时, NumberAnimation会被应用;

NumberAnimation类型应用基于一个数字值的改变, 我们对Row的opacity属性, 在350毫秒时长内显示它;

Note NumberAnimation类型是继承自PropertyAnimation, 它有一个 Easing.Linear作为 easing curve动画的默认值; [动画效果, 运行轨迹等...]

下一步

我们可以看到如何使用Transition和其他QML Animation实现动画效果;

5.2 使用State和Transition

前面我们看到的定义简单的话的技巧是基于属性变化的, 使用了 Behavior和 NumberAnimation;

当然, 也有其他动画是依赖于一组属性变化的--可以用State实现;

现在来看看怎样进一步实现NoteApp的UI;

Marker item看起来在用户交互的时候是静态的; 如果基于用户交互的不同场景给它加上一点动画会怎样? 另外, 我们可以可以让当前激活的marker和当前的page对用户来说看起来更明明确;

5.2.1 Marker Items加上动画

我们差不多可以总结一下在用户交互时改进Marker item的各种可能的场景, 以下是user case(用户用例)描述:

- 当前激活的Marker item应该更加明显; 用户点击的时候, 一个marker要变成激活状态; 激活的marker会稍微变大, 可以从左边向右边滑动一些;(像个抽屉)

- 当用户鼠标悬停在一个marker上面, marker从左到右滑动, 但不会像激活的marker一样滑动;

考虑上述场景, 我们需要在Marker和MarkerPanel组件上进行工作;

当独当上面关于行为需求的描述(左到右的滑动效果), 立即出现的想法是改变 x的属性, 因为它代表了item在X-axis(轴)上的位置; 另外, 由于Marker item应该要知道它自己是否是当前激活的, 因此添加一个新的属性 active;

为Marker组件引入两个新的state, 代表上面描述的行为:

- hovered: 当用户鼠标悬停的时候会更新marker的x属性值;

- selected: 当marker被激活, 即用户点击的时候, 会更新x属性值;

// Marker.qml


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

//
this property indicates whether this marker item

//
is the current active one. Initially it is set to false

property
bool active: 
false

//
creating the two states representing the respective

//
set of property changes

states:
[

    //
the hovered state is set when the user has

    //
the mouse hovering the marker item.

    State
{

        name: "hovered"

        //
this condition makes this state active

        when:
mouseArea.containsMouse && !root.active

        PropertyChanges
{ target: root; x: 5 }

    },

    State
{

        name: "selected"

        when:
root.active

        PropertyChanges
{ target: root; x: 20 }

    }

]

//
list of transitions that apply when the state changes

transitions:
[

    Transition
{

        to: "hovered"

        NumberAnimation
{ target: root; property: 
"x";
duration: 300 }

    },

    Transition
{

        to: "selected"

        NumberAnimation
{ target: root; property: 
"x";
duration: 300 }

    },

    Transition
{

        to: ""

        NumberAnimation
{ target: root; property: 
"x";
duration: 300 }

    }

 ]

因此我们声明两个state代表相应基于用户行为的属性变化; 每个state绑定到when属性所描述的情况中;

Note 对于MouseArea的containsMouse属性, hoverEnabled属性必须设为true;

Transition是用来在state之前切换时定义item的行为的; 我们可以在state激活的时候, 给变化的属性定义各种动画

Note item的默认state是一个空的string--("");

在MarkerPanel组件里, 我们在它被点击的时候必须设置avtive属性为true; 参考MarkerPanel.qml;

5.2.2 给PagePanel添加Transition

在PagePanel组件, 我们使用state来管理page之间的navigation(导航); 添加transition是自然的思路; 由于我们在每个state里面改变了opacity属性, 可以添加给所有的state添加Transition来根据opacity的值运行NumberAnimation, 创建fade-in和fade-out效果;

// PagePanel.qml


1

2

3

4

5

6

7

8

9

10

//...

    //
creating a list of transitions for

    //
the different states of the PagePanel

    transitions:
[

    Transition
{

        //
run the same transition for all states

        from: "";
to: 
"*"

        NumberAnimation
{ property: 
"opacity";
duration: 500 }

    }

    ]

Note 一个item的opacity值也会被传播(propagated)到它的child元素;

下一步

进一步改进UI;

---5End---

CHAPTER6 更多改进

这一阶段, 可以认为NoteApp的特性完成, UI也符合需求; 不过, 这里还有很大空间改进, 虽然不是最重要(minor)但可以使得程序更漂亮, 以及准备部署(deployment);

这一章有些小的改进, 也有些新的主意和特性添加进来; 当然, 我们可以鼓励继续开发NoteApp, 或许重新设计整个UI, 引入更多特性;

这里有一个要点列表:

- 更多Javascript用来添加功能;

- 使用QML Item的z ordering(z轴次序);

- 使用自定义的本地字体;

6.1 加强Note Item的功能

一个巧妙的(nifty)功能可以让note根据输入的text而变长; 为了简化, 当更多text输入时, 它会将text折叠(wrap)起来, 适应note宽度, 在垂直方向上将note变长;

Text类型有一个paintedHeight属性给出text在屏幕上绘制时的确切高度; 根据这个值, 我们可以增加或减少note自身的高度;

先定义一个Javascript helper方法, 为Item计算height属性的值, 它会放在Note组件的顶层;

// Note.qml


1

2

3

4

5

6

7

8

9

10

//
JavaScript helper function that calculates the height of

//
the note as more text is entered or removed.

function updateNoteHeight()
{

    //
a note should have a minimum height

    var noteMinHeight
= 200

    var currentHeight
= editArea.paintedHeight + toolbar.height +40

    root.height
= noteMinHeight

    if(currentHeight
>= noteMinHeight)

        root.height
= currentHeight

}

由于 updateNoteHeight()方法会根据editArea的paintedHeight属性更新root的height, 我们需要在paintedHeight变化的时候调用这个方法;

// Note.qml


1

2

3

4

5

6

7

8

TextEdit
{

    id:
editArea

    //...

    //
called when the painterHeight property changes

    //
then the note height has to be updated based

    //
on the text input

    onPaintedHeightChanged:
updateNoteHeight()

//...

Note 每个属性有一个notifier signal(通知信号), 每次property改变的时候会被发送(emit);

updateNoteHeight() JS方法会改变height属性, 所以我们可以使用Behavior定义一个行为;

// Note.qml


1

2

3

4

//...

//
defining a behavior when the height property changes

//
for the root element

Behavior
on height { NumberAnimation {} }

下一步

展示如何使用Item的z属性来正确地为note排序;

6.2 Note排序

Page里面的Note无法知道用户当前正在使用哪一个note; 默认情况, 所有创建出来的Note item都有一样的z属性默认值, 这种情况下, QML为item创建默认的栈次序, 依赖于哪一个item先被创建;

所需要的行为应该是根据用户交互来改变note的次序; 当用户点击note toolbar, 或者开始编辑note的时候, 当前的note应该跑到前面而不是躲在其他note下面; 这可以通过改变z值来做到, z值比其他的note高即可;

// Note.qml


1

2

3

//...

//
setting the z order to 1 if the text area has the focus

z:
editArea.activeFocus ? 1:0

activeFocus属性在editArea有输入焦点(input focus)的时候变为true; 因此让z属性依赖editArea的activeFocus会比较安全; 然后, 我们需要保证editArea在用户点击toolbar的时候有输入焦点; 我们在NoteToolbar组件中定义一个pressed()信号, 在鼠标press的时候发送;

// NoteToolbar.qml


1

2

3

4

5

6

7

8

9

10

11

//...

    //
this signal is emitted when the toolbar is pressed by the user

    signal
pressed()

    //
creating a MouseArea item

    MouseArea
{

        id:
mousearea

//...

        //
emitting the pressed() signal on a mouse press event

        onPressed:
root.pressed()

    }

在MouseArea中的onPressed信号handler中, 我们发送NoteToolbar(root)的pressed()信号;

NoteToolbar的pressed()信号在Note组件中会处理;

// Note.qml


1

2

3

4

5

6

    //
creating a NoteToolbar that will be anchored to its parent

    NoteToolbar
{

        id:
toolbar

        //
setting the focus on the text area when the toolbar is pressed

        onPressed:
editArea.focus = 
true

//...

上面代码中, 我们将editArea的focus属性设为true, editArea会接收到输入焦点; 这样activeFocus属性变为true, 触发(trigger)z属性值的变化;

下一步

怎样加载以及使用一个自定义的本地font(字体)文件;

6.3 加载自定义字体

在现代程序中使用部署一个自定义的font而不依赖系统font是很常见的方式; 对于NoteApp, 我们想要用QML提供的方法做相同的事情;

FontLoader类型让你可以通过名字或URL路径来加载font; 因为加载的font可以被整个程序广泛使用, 我们建议在main.qml中加载它, 然后在其他组件中使用;

// main.qml


1

2

3

4

5

6

7

8

9

10

11

//...

    //
creating a webfont property that holds the font

    //
loading using FontLoader

    property var webfont:
FontLoader {

        id:
webfontloader

        source: "fonts/juleeregular.ttf"

        onStatusChanged:
{

        if (webfontloader.status
== FontLoader.Ready)

            console.log("font----Loaded")

        }

    }

这样我们已经为window item创建了一个webfont属性; 这个属性可以安全地在其他的组件中使用, 可以在editArea的Note组件中使用;

// Note.qml


1

2

3

4

    TextEdit
{

        id:
editArea

        font.family:
window.webfont.name; font.pointSize: 13

//...

要设置editArea的font, 使用font.family属性; 通过window, 我们使用它的webfont属性来获取font名字, 用来设置;

下一步

将NoteApp准备好部署的细节;

---6End---

---TBC---YCR---

时间: 2024-10-09 22:58:19

QtQuick桌面应用开发指导 4)动态管理Note对象_B 5)外观加强 6)更多改进的相关文章

QtQuick桌面应用开发指导 3)实现UI和功能_B 4)动态管理Note对象_A

3.2 把Page Item和Marker Item绑定 之前我们实现了PagePanel组件, 使用了三个state来切换Page组件的opacity属性; 这一步我们会使用Marker和MarkerPanel组件来实现页面导航; 在原型阶段, MarkerPanel组件十分简单, 没有任何功能; 它使用了Repeater类型来产生三个QML Item以及Marker组件作为delegate; MarkerPanel应该存储当前激活的marker(标记), 即那个被用户点击的marker; 基

QtQuick桌面应用开发指导 7)创建应用 8)扩展

CHAPTER7 部署NotApp应用 现在我们要让程序在典型的桌面环境中可用, 可部署; 如第一章所描述, 我们在QtCreator中使用QtQuick UI项目开发NoteApp程序; 这意味着qmlscene用来加载main.qml, 随之让NoteApp运行; 首先, 让NoteApp可用的最简单方案是创建一个package(包)将所有qml文件, qmlscense和一个可以运行qmlscense加载main.qml的简单脚本bundle(捆扎)起来; 你需要参考每一个桌面平台, 了解

QtQuick桌面应用开发指导 1)关于教程 2)原型和设计 3)实现UI和功能_A

Release1.0 http://qt-project.org/wiki/developer-guides Qt Quick Application Developer Guide for Desktop 这个教程的目的是让你熟悉使用QtQuick构建QML程序的最佳编程实践方法; 先决条件: 对QML有相当的理解, 相关阅读: <qtquick/qtquick-applicationdevelopers.html>; 本教程会涉及QML开发最佳实践的各个方面, 以及在典型的桌面环境下部署应

QtQuick桌面应用程序开发指导 3)达到UI而功能_B 4)动态管理Note物_A

3.2 把Page Item和Marker Item绑定 之前我们实现了PagePanel组件, 使用了三个state来切换Page组件的opacity属性; 这一步我们会使用Marker和MarkerPanel组件来实现页面导航; 在原型阶段, MarkerPanel组件十分简单, 没有不论什么功能; 它使用了Repeater类型来产生三个QML Item以及Marker组件作为delegate; MarkerPanel应该存储当前激活的marker(标记), 即那个被用户点击的marker;

Jetty开发指导:Maven和Jetty

使用Maven Apache Maven是一种软件项目管理和综合工具.基于项目对象模型(POM)的概念,Maven能从核心信息管理一个项目的构建.报告和文档. 他是用于构建一个web应用项目的理想工具,这些项目能用jetty-maven-plugin轻松的运行web应用,从而节省开发时间.你也能用Maven构建.测试和运行一个嵌入Jetty的项目. 首先我们将看一个很简单嵌入Jetty的HelloWorld Java应用,然后看一个简单的webapp怎么使用jetty-maven-plugin加

Qt Quick应用开发介绍 10-12(动态界面, 实践学习, 总结和扩展)

Chapter10 UI Dynamics and Dynamic UI 动态界面 前面章节学习了在开发时添加item, 让它们invisible; 该怎么做可以让程序根据不同的数据和用户输入来有不同的显示? 这些变化可能比visibility复杂; 我们怎样才能做到让程序UI的动态变化更appealing吸引人, 甚至成为用户体验的一部分? 10.1 Using States 使用state 网络连接对于现在的版本中天气相关的部件是必须的; 它让网络数据可视化; 如果你的电脑不在线, 启动cl

干货系列2:看看Java桌面应用开发的职业发展空间与必备技能

导读: 我前面两篇文章分别写了java软件开发和java互联网开发工程师的职业发展和技能要素,今天说一说Java桌面应用开发的程序员,他们一般来说对未来发展尤为困惑,确实,用Java可以创建出桌面应用,但只要我们想开发真正的富桌面应用,还需要使用JNI.C/C++等等技能.所有,也许了解如何系统的建立自己的知识体系,是你困惑的的根本原因. 所以,如果你正在(或未来)做Java桌面应用开发,并且对你未来的职业道路感到迷茫和不知所措.跟我来,我将就java桌面应用的发展路线和所需要的技能一一说明,或

ios开发-UI基础-应用管理(单纯界面)改进2

本篇文章,通过字典转模型来改进上篇文章中的代码. 字典转模型,之前的文章已经介绍过,这里再重复一下:  字典转模型 字典:用来存储数据的,用键值对存储数据,是一个nsdictionary ,(不好处:key值容易写错) 模型: 用来存储数据的,一个字典对应一个模型,模型用属性来存储数据,是一个纯洁的object对象 @property(nonatomic,copy)NSString *name; @property(nonatomic,copy)NSString *icon; 字典转模型:一个字

专注智慧城市项目开发,智慧城市管理建设

专注智慧城市项目开发,智慧城市管理建设(作者:ruiec_wangxuyan) 智慧城市是按照科学的城市发展理念,利用新一代信息技术,在信息全面感知和互联的基础上,实现人.物.城市功能系统之间无缝连接与协同联动,达到城市管理智能自感知.自适应.自优化,形成具备可持续内生动力的安全.便捷.高效.绿色的城市形态,以推进实体基础设施和信息设施相融合.构建城市智能基础设施为基础,以物联网.云计算.移动互联网等新一代信息通信技术在城市各领域的充分运用为主线,通过高科技的应用解决方案,提升城市运行管理水平.