一、效果展示

  今儿来分析一篇常见的ui布局,完全使用qml编写,ui交互效果友好,如图1所示,是一个常见的客户端新闻展示效果,左侧是一个列表,右侧是新闻详情。

图1 新闻效果图

二、源码分析

  首先先来总体分析下该示例代码的工程目录,如图2所示,总共有6个qml文件。其中BusyIndicator和ScrollBar组件是qml已经存在的组件,NewsDelegate组件是新闻详情页中的一项,CategoryDelegate组件是左侧列表中的一项,RssFeeds组件是左侧新闻列表数据源,rssnews文件是主程序文件。

图2 工程目录

  结合图1看程序工程目录,是不是觉着一目了然。NewsDelegate组件和CategoryDelegate组件是两个绘制代理,RssFeeds组件提供一个视图数据源,其中还有一个视图的数据源在rssnews.qml文件内部定义。接下来我主要分析下主程序文件rssnews.qml和NewsDelegate绘制代理

1、主程序文件

  主程序文件代码如下,程序中关键的地方都有注释,相比于之前的文章注释少了许多,大多都是一些常见的属性没有了注释。

 import QtQuick 2.2
import QtQuick.XmlListModel 2.0
import QtQuick.Window 2.1
import "./content" Rectangle {
id: window width:
height: property string currentFeed: rssFeeds.get().feed//get方法为ListModel内置方法,返回指定索引item
property bool loading: feedModel.status === XmlListModel.Loading//是否是加载中。。。
property bool isPortrait: Screen.primaryOrientation === Qt.PortraitOrientation onLoadingChanged: {
if (feedModel.status == XmlListModel.Ready)
list.positionViewAtBeginning()
} RssFeeds { id: rssFeeds } XmlListModel {
id: feedModel source: "http://" + window.currentFeed
query: "/rss/channel/item[child::media:content]"
namespaceDeclarations: "declare namespace media = 'http://search.yahoo.com/mrss/';" XmlRole { name: "title"; query: "title/string()" }
// Remove any links from the description
XmlRole { name: "description"; query: "fn:replace(description/string(), '\<a href=.*\/a\>', '')" }
XmlRole { name: "image"; query: "media:content/@url/string()" }
XmlRole { name: "link"; query: "link/string()" }
XmlRole { name: "pubDate"; query: "pubDate/string()" }
} ListView {//左侧新闻列表
id: categories
property int itemWidth: width: isPortrait ? parent.width : itemWidth
height: isPortrait ? itemWidth : parent.height
orientation: isPortrait ? ListView.Horizontal : ListView.Vertical
anchors.top: parent.top
model: rssFeeds
delegate: CategoryDelegate { itemSize: categories.itemWidth }
spacing:
} ScrollBar {
id: listScrollBar orientation: isPortrait ? Qt.Horizontal : Qt.Vertical
height: isPortrait ? : categories.height;
width: isPortrait ? categories.width :
scrollArea: categories;//关联滚动的区域
anchors.right: categories.right//锚点定位
} ListView {//右侧新闻详情 由多个项NewsDelegate组成
id: list anchors.left: isPortrait ? window.left : categories.right
anchors.right: closeButton.left
anchors.top: isPortrait ? categories.bottom : window.top
anchors.bottom: window.bottom
anchors.leftMargin:
anchors.rightMargin:
clip: isPortrait
model: feedModel
footer: footerText//页脚 视图最底部的修饰
delegate: NewsDelegate {}
} ScrollBar {
scrollArea: list
width:
anchors.right: window.right
anchors.top: isPortrait ? categories.bottom : window.top
anchors.bottom: window.bottom
} Component {
id: footerText Rectangle {
width: parent.width
height: closeButton.height
color: "lightgray" Text {
text: "RSS Feed from Yahoo News"
anchors.centerIn: parent
font.pixelSize:
}
}
} Image {//关闭按钮 点击退出程序
id: closeButton
source: "content/images/btn_close.png"
scale: 0.8
anchors.top: parent.top
anchors.right: parent.right
anchors.margins:
opacity: (isPortrait && categories.moving) ? 0.2 : 1.0
Behavior on opacity {
NumberAnimation { duration: ; easing.type: Easing.OutSine }
} MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit()
}
}
}
}

  footer属性指定页脚,就像word文件的页脚一样,位于ListView最低端,如图1中第一帧的RSS Feed from Yahoo News字段,其实每个页面都有这个字段,只是都位于ListView内容最低端。

2、新闻详情页中项

  如图1所示,该NewsDelegate绘制代理是右侧页面中的一条新闻项,右侧页面是一个ListView,内部有许多项组成,每一项都是由该代理绘制。

 //新闻详情中的一条
import QtQuick 2.2 Column {
id: delegate
width: delegate.ListView.view.width
spacing: // Returns a string representing how long ago an event occurred
function timeSinceEvent(pubDate) {
var result = pubDate; // We need to modify the pubDate read from the RSS feed
// so the JavaScript Date object can interpret it
var d = pubDate.replace(',','').split(' ');
if (d.length != )
return result; var date = new Date([d[], d[], d[], d[], d[], 'GMT' + d[]].join(' ')); if (!isNaN(date.getDate())) {
var age = new Date() - date;
var minutes = Math.floor(Number(age) / );
if (minutes < ) {
if (minutes < )
result = qsTr("Just now");
else if (minutes < )
result = '' + minutes + ' ' + qsTr("minutes ago")
else if (minutes < )
result = qsTr("1 hour ago");
else
result = '' + Math.floor(minutes/) + ' ' + qsTr("hours ago");
}
else {
result = date.toDateString();
}
}
return result;
} Item { height: ; width: delegate.width } Row {
width: parent.width
spacing: Column {
Item {//占位
width:
height: titleText.font.pixelSize /
} Image {
id: titleImage
source: image//image对应模型中的字段
}
} Text {
id: titleText text: title//image对应模型中的字段
width: delegate.width - titleImage.width
wrapMode: Text.WordWrap
font.pixelSize:
font.bold: true
}
} Text {//距离新闻发布时间+带有link字样的超链接
width: delegate.width
font.pixelSize:
textFormat: Text.RichText
font.italic: true
text: timeSinceEvent(pubDate) + " (<a href=\"" + link + "\">Link</a>)"
onLinkActivated: {
Qt.openUrlExternally(link)//link对应模型中的字段
}
} Text {
id: descriptionText text: description//对应模型中的字段
width: parent.width
wrapMode: Text.WordWrap//换行模式 字不能拆分
font.pixelSize: //字号
textFormat: Text.StyledText//支持一些基本的文本样式标记
horizontalAlignment: Qt.AlignLeft//水平靠左
}
}

三、小节

  看了有一些qml示例代码,也一直主要在分析qml代码,本小节插播一段个人总结吧,也算是小小感慨下。

  不同于以往的QWidget窗口程序,qml写界面非常简洁,从以往的示例中就能感觉的到,在友好交互方面qml比QWidget做的好,比如List下拉到头时的弹簧效果、完美的加载中展示和远程图片加载等等。qml是声明性语言,即不在像C++那样需要编译后才能运行,在代码编写时只需要关注ui,可以根据需要自己封装组件,把需要外界使用的属性使用导出的方式暴露给外界,每一个组件属性都有OnPropertyChanged槽,当属性发生变化时该槽随即执行。

  可能是由于一直从事C++相关的工作,没有声明性语言的基础,在阅读qml代码时总是感觉有一种代码散乱无处整理的感觉,现在小小的示例代码亦是如此,等到正真做起项目来不知道会是怎样一番场景。比如说绘制代理在访问一些属性时,直接访问的是模型中的字段,如果字段名称写错,这种错误只能到运行时异常后才能慢慢排查,类似于这样的代码其实有很多,突然之间就跳出一句无厘头的代码,这在C++中根本不可能出现。。。呵呵呵。。。

qml demo分析(rssnews-常见新闻布局)的更多相关文章

  1. qml demo分析(threadedanimation-线程动画)

    一.效果预览 使用过qml的同学都知道,使用qml做动画效果是非常简单的,再也不需要像QWidget那样,自己模拟一个动画,费时又费力,往往还达不到效果.今天我们就来分析下qml的两种动画实现方式,如 ...

  2. qml demo分析(maskedmousearea-异形窗口)

    一.效果展示 如本文的标题所示,这篇文章分析的demo是一个异形窗口,主要展示鼠标在和异形区域交互的使用,效果如图1所示,当鼠标移动到白云或者月亮上时,相应的物体会高亮,当鼠标按下时,物体会有一个放大 ...

  3. qml demo分析(maroon-小游戏)

    1.效果展示 这篇文章我还是分析一个qt源码中的qml程序,程序运行效果如下图所示. 图1  游戏开始 图2  游戏中 2.源码分析 这个游戏的源码文件比较多,为了能更清楚的了解整个代码,我先整体分析 ...

  4. qml demo分析(externaldraganddrop-拖拽)

    一.效果展示 客户端程序拖拽是一个很常见的需求,对于QWidget程序来说,需要重写如图1这么几个方法,通过重写这几个方法的逻辑,我们就可以控制鼠标拖拽的逻辑,糟糕的是QDrag执行exec后是一个阻 ...

  5. qml demo分析(text-字体展示)

    上一篇文章分析了一个小游戏,使用qml编写界面+js进行复杂逻辑控制,算是一个比较完整的qml示例代码了,今天就不那么继续变态啦,来看一个简单的字体示例程序吧,该示例代码比较简单,主要是展示了几个简单 ...

  6. qml demo分析(samegame-拼图游戏)

    一.效果展示 相信大家都玩儿过连连看游戏,而且此款游戏也是闲时一款打发时间的趣事,那么接下来我将分析一款类似的游戏,完全使用qml编写界面,复杂逻辑使用js完成.由于此游戏包含4种游戏模式,因此本篇文 ...

  7. qml demo分析(abstractitemmodel-数据分离)

    一.概述 qt5之后qml也可以被用于桌面程序开发,今天我就拿出qt demo中的一个qml示例程序进行分析.这个demo主要是展示了qml数据和展示分离的使用方式,qml只专注于快速高效的绘制界面, ...

  8. qml demo分析(threading-线程任务)

    一.关键类说明 qml内置了WorkerScript组件,该组件有一个source属性,可以加载js文件,含有一个名为message的信号,意味着他有一个默认的onMessage槽函数,除此之外他还有 ...

  9. qml demo分析(photosurface-图片涅拉)

    阅读qml示例代码已有一小段时间,也陆续的写了一些自己关于qml示例代码的理解,可能由于自己没有大量的qml开发经验,总感觉复杂的ui交互qml处理起来可能会比较棘手,但事实总是会出人意料,今天我们就 ...

随机推荐

  1. css3 绘制图形

    星形: .star-six { width:; height:; border-left: 50px solid transparent; border-right: 50px solid trans ...

  2. Python中标准模块importlib详解

    1 模块简介 Python提供了importlib包作为标准库的一部分.目的就是提供Python中import语句的实现(以及__import__函数).另外,importlib允许程序员创建他们自定 ...

  3. 安卓----Spinner

    <?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android=" ...

  4. Go的context的问题

    Go的context的问题 2017-05-29 最近被由context引发的一个bug坑得不轻,所以反思一下Go的context的问题. context是隐式的约束,没有检测 如果我们写一个函数,比 ...

  5. C# WinForm ShowInTaskbar Api Version

    using System; using System.Runtime.InteropServices; namespace x { unsafe class NativeWindow { /* * W ...

  6. 单例模式--java代码实现

    单例模式 单例模式,顾名思义,在程序运行中,实例化某个类时只实例化一次,即只有一个实例对象存在.例如在古代,一个国家只能有一个皇帝,在现代则是主席或总统等. 在Java语言中单例模式有以下实现方式 1 ...

  7. 新手教程:不写JS,在MIP页中实现异步加载数据

    从需求谈起:在 MIP 页中异步加载数据 MIP(移动网页加速器) 的 加速原理 除了靠谱的 MIP-Cache CDN 加速外,最值得一提的就是组件系统.所有 JS 交互都需要使用 MIP 组件实现 ...

  8. 亲测可用,iptables实现NAT转发。

    环境 服务器A:192.168.1.7 服务器B: 192.168.1.160 需求 实现将本机(192.168.1.7:7410)端口流量转发给(192.168.1.160:9200). 1. 内核 ...

  9. frida的用法--Hook Java代码篇

    frida是一款方便并且易用的跨平台Hook工具,使用它不仅可以Hook Java写的应用程序,而且还可以Hook原生的应用程序. 1. 准备 frida分客户端环境和服务端环境.在客户端我们可以编写 ...

  10. Boosting(提升方法)之AdaBoost

    集成学习(ensemble learning)通过构建并结合多个个体学习器来完成学习任务,也被称为基于委员会的学习. 集成学习构建多个个体学习器时分两种情况:一种情况是所有的个体学习器都是同一种类型的 ...