Qt Quick之StackView详解(1)

Qt Quick中有个StackView,我在《Qt Quick核心编程》一书中没有讲到,最近有人问起,趁机学习了一下,把它的基本用法记录下来。

我准备分两次来讲。第一次讲基本的用法,包括StackView的适用场景、基本属性和方法的用法。第二次讲一些稍微复杂点的东西,比如被StackView管理的view的生命周期、delegate定制、查找等。

示例会用到动态创建组建,可以参考我之前的文章“Qt Quick 组件与对象动态创建详解”。也会用到锚布局,参考“Qt Quick 布局介绍”。还会用到Button、Rectangle、MouseArea、Text等基本元素,请参考《Qt Quick核心编程》一书。

StackView介绍

StackView实现了一个栈式的导航。“”大家都知道是怎么回事儿,就是一种数据结构,先进后出(FILO),支持pop、push等操作。StackView用于栈类似的行为方式管理一系列的View(页面或视图),这些View之间可能有内在联系,根据业务需要,可以一级一级向深处的跳转,当前的View上发生点儿什么事儿,就可能会产生一个新的View或返回之前的页面。

举两个简单的场景。

比如注册账号这个场景,有一种做法是分几个步骤,比如第一步先让你输入用户名、密码,你点击下一步之后呢,会出现新的页面,接着让你输入姓名、爱好、邮箱、社交方式等。

比如你在某个招聘网站提交简历,先是填写基本信息,如姓名、毕业院校、联系方式、求职意向等,然后下一步,就让你添加工作经验……一路Next下去即可。说到这里你可以看看我之前写的一篇文章,史上最全的程序员求职渠道总结

StackView是FocusScope的子类,FocusScope是Item的子类。从这个继承关系来看,StackView要作为一个Window的孩子(孩子的孩子也可以,孩子的孩子的孩子也可以……)来使用。当然如果你用QQuickView来加载main.qml的话,StackView也可以作为main.qml的根节点,不必嵌套在一个Window里。

StackView有几个属性:

  • busy 指示StackView是否正在应用过渡动画,为true时表示正在应用动画。可以通过属性变化信号处理器onBusyChanged来响应busy属性变化,结合我们的业务需求来做一些处理,比如在动画期间禁止用户点击。
  • currentItem 指向栈顶的View(Item),可能为空。
  • delegate 用于定制页面切换时的过渡动画。
  • depth 栈的深度,StackView中没有子页面时,depth为0,有一个子页面时,depth为1……
  • initialItem 初始的View(Item)。我们可以通过这个属性来指定StackView管理的第一个页面(View),如果你在初始化时给initalItem赋值,效果就相当于我们在Component.onCompleted信号处理器中调用 push(yourItem)。如果你不显式给initalItem赋值,当第一个页面被push进StackView时,这个属性也会被自动赋值。

StackView有几个方法:

  • clear(),顾名思义,干掉StackView管理的所有页面
  • pop(item),出栈操作。无参调用pop时,讲栈顶的页面弹出。如果带参数,则将参数指定的页面之后的所有页面都弹出。举个例子吧,现在栈内页面时酱紫的,[A,B,C,D,E],pop()调用后,就变为[A,B,C,D]。你再调用pop(B),就会变成[A,B]。
  • push(item),入栈操作,参数是Item,将一个页面压入StackView。这个页面(Item)一般是动态创建的。待会儿我们的示例可以看到。有一个特别的用法,可以替换栈顶元素,比如你的栈是[A,B,C,D],push(E, replace),就会用E替换栈顶的D,栈就会变为[A,B,C,E]。关于push,还有一些其它用法,参考Qt帮助吧。
  • find(func, onlySearchLoadedItems),查找StackView管理的某个页面。find将对栈内的每个页面应用func方法,当func返回true时,表示找到了,查找过程就会停止,然后find会返回找到的那个Item。
  • completeTransition(),立即结束过渡动画。

再啰嗦几句吧。StackView本身其实是一个正常的Item,这从它的类继承关系可以看出来。所以呢,你可以指定它的大小(width、height),也可以使用anchors等布局。StackView管理的页面,都会作为StackView的孩子,这些子View们,默认会充满StackView的可用区域,我们不能使用anchors来布局子页面,假如你为子View使用了anchors,那页面切换时的动画效果就会失效。还有一点,指定子页面的大小(width、height)也不管用。所以,省事儿啦。

StackView示例

设计了一个非常简单的示例,效果如下图所示:

我们看到,在上面的GIF中,点击Next按钮会新创建一个页面并将这个页面加入到StackView中,页面切换时有一个动画效果。这个动画效果是StackView提供的默认效果,如果我们想改变它,就可以通过delegate属性来定制。

所有代码在这里了:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2

Window {
    title: "StackViewDemo";
    width: 480;
    height: 320;
    visible: true;

    StackView {
        id: stack;
        anchors.centerIn: parent;
        width: 600;
        height: 300;
        property var home: null;

        Text {
            text: "Click to create first page";
            font.pointSize: 14;
            font.bold: true;
            color: "blue";
            anchors.centerIn: parent;
            MouseArea {
                anchors.fill: parent;
                onClicked: if(stack.depth == 0)stack.push(page);
            }
        }
    }

    Component {
        id: page;

        Rectangle {
            color: Qt.rgba(stack.depth*0.1, stack.depth*0.2, stack.depth*0.3);

            Text {
                anchors.centerIn: parent;
                text: "depth - " + stack.depth;
                font.pointSize: 24;
                font.bold: true;
                color: stack.depth <= 4 ? Qt.lighter(parent.color) : Qt.darker(parent.color);
            }

            Button {
                id: next;
                anchors.right: parent.right;
                anchors.bottom: parent.bottom;
                anchors.margins: 8;
                text: "Next";
                width: 70;
                height: 30;
                onClicked: {
                    if(stack.depth < 8) stack.push(page);
                }
            }

            Button {
                id: back;
                anchors.right: next.left;
                anchors.top: next.top;
                anchors.rightMargin: 8;
                text: "Back";
                width: 70;
                height: 30;
                onClicked: {
                    if(stack.depth > 0) stack.pop();
                }
            }

            Button {
                id: home;
                anchors.right: back.left;
                anchors.top: next.top;
                anchors.rightMargin: 8;
                text: "Home";
                width: 70;
                height: 30;
                onClicked: {
                    if(stack.depth > 0)stack.pop(stack.initialItem);
                }
            }

            Button {
                id: clear;
                anchors.right: home.left;
                anchors.top: next.top;
                anchors.rightMargin: 8;
                text: "Clear";
                width: 70;
                height: 30;
                onClicked: {
                    if(stack.depth > 0)stack.clear();
                }
            }
        }
    }
}

简单解释一下上面的代码,id为stack的StackView,内部放了一个Text元素,点击时创建第一个页面。页面由内嵌在main.qml中的Component提供。

id为page的组件,顶层元素是个Rectangle对象,颜色由StackView的depth属性决定。这个Rectangle内部,中间放了一个Text,底部放了Clear、Home、Back、Next几个按钮,在这些按钮的onClicked信号处理器中,调用了StackView的clear、pop、push等方法。

你可以使用qmlscene来加载示例qml文档,也可以通过Qt Creator创建一个Qt Quick App来查看效果。建议使用Qt SDK 5.3.0及以上版本。

OK,这次就先到这里了。下次我们来讲StackView管理的页面(View)的生命周期、查找View、动画定制等内容。



更多Qt Quick文章请参考我的Qt Quick专栏

,想系统学些Qt Quick(QML),请阅读《Qt Quick核心编程》。

我开通了微信订阅号“程序视界”,关注即可第一时间看到我的原创文章以及我推荐的精彩文章:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-11 01:34:20

Qt Quick之StackView详解(1)的相关文章

Qt Quick之StackView详解(2)

在"StackView详解(1)"中,我们学习了StackView的基本用法,这次呢,我们来讲delegate的定制.被管理的View的生命周期.查找View等主题. 本文还会用到"StackView详解(1)"中的示例,如有需要可以回头看看. 附加属性 首先看看StackView提供的附加属性 Stack(后面会用到): Stack.index,index代表当前Item在StackView里的索引,从0开始哦,和StackView.depth不同哦,depth从

Qt Quick 之 PathView 详解

开始的开始,请给我的决赛博文投票:点此进入投票页面,网页最下方有投票按钮,投我一票,谢谢. PathView ,顾名思义,沿着特定的路径显示 Model 内的数据. Model 可以是 QML 内建的 ListModel . XmlListModel ,也可以是在 C++ 中实现的 QAbstractListModel 的派生类. PathView 恐怕是 Qt Quick 提供的 Model-View 类库中最复杂也最灵活的一个了. 要使用一个 PathView ,至少需要设置 model .

Qt Quick之StackView具体解释(1)

Qt Quick中有个StackView.我在<Qt Quick核心编程>一书中没有讲到.近期有人问起,趁机学习了一下,把它的基本使用方法记录下来. 我准备分两次来讲.第一次讲主要的使用方法.包含StackView的适用场景.基本属性和方法的使用方法.第二次讲一些略微复杂点的东西,比方被StackView管理的view的生命周期.delegate定制.查找等. 演示样例会用到动态创建组建,能够參考我之前的文章"Qt Quick 组件与对象动态创建具体解释".也会用到锚布局.

QT中的qmake详解

关于qmake,好一段时间令我一头雾水,不知道用来干嘛的,只知道怎么用,而且也只懂那么一两个命令,详细看过资料以后整理如下: 1.首先,感性的认识是,qmake可以利用源文件(包括头文件h,实现文件cpp,qt的ui文件等等)生成各种不同类型的工程,工程需要的Makefile文件,可执行的与不可执行的,这取决于所用的模板(包括app.lib.subdirs.vcapp.vclib). 2.创建pro文件,添加各种源文件,还可以设定平台相关的不同源文件,设置各种规则,利用qmake命令生成工程.后

Qt QTableview的用法详解

本文转自http://www.360doc.com/content/14/0210/11/3300331_351302235.shtml 一. 对QTableWidget本身的效果实现 1. 将表格变为禁止编辑 在默认情况下,表格里的字符是可以更改的,比如双击一个单元格,就可以修改原来的内容,如果想禁止用户的这种操作,让这个表格对用户只读,可以这样: tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); QAbstrac

QT中QProcess调用详解及实验

在QT程序中需要将某目录和文件压缩为一个rar的压缩包,于是想到了在QT中通过QProcess类调用命令行的rar.exe来达到效果,但是没想到QProcess类用起来很麻烦,而且达不到效果,折腾了2天仍然没找到原因,使用另外一种办法解决了. 创建压缩包的方法 在windows平台创建压缩包,可以直接使用rar.exe,该程序在安装winrar之后,在其安装目录下就可以找到.该程序是winrar对应的命令行版本,其语法例子如下: rar.exe a -k -r -s -m1 test.rar d

关于QT的QPainterPath::arcTo 详解

这个函数文档的意思就是画弧,看了文档也不太明白,自己做了demo终于明白了意思 移动到圆心,画180度半圆 void TestArcTo::paintEvent(QPaintEvent *) { QPoint startPt(30, 30); QRect rect(startPt.x(), startPt.y(), 200, 200); QPainter p(this); p.setRenderHint(QPainter::Antialiasing); //抗锯齿 p.fillRect(rect

Qt Quick核心编程从入门到精通

本文是个推荐文章,推荐foruok博主的Qt quick 核心编程的系列经典编程! foruok 博主 的Qt Quick系列文章: Qt Quick 简介 QML 语言基础 Qt Quick 之 Hello World 图文详解 Qt Quick 简单教程 Qt Quick 事件处理之信号与槽 Qt Quick事件处理之鼠标.键盘.定时器 Qt Quick 事件处理之捏拉缩放与旋转 Qt Quick 组件与对象动态创建详解 Qt Quick 布局介绍 Qt Quick 之 QML 与 C++

Qt Quick里的图形效果——渐变(Gradient)

Qt Quick提供了三种渐变图形效果: ConicalGradient,锥形渐变 LinearGradient,线性渐变 RadialGradient,径向渐变 效果 下图是我设计的示例效果: 图 1 渐变图形效果 如图所示,第一行为线性渐变,第二行为锥形渐变,第三行为径向渐变. 渐变元素与其他图形效果元素不同之处在于:渐变元素既可以用来改变一个已有的元素(如Image),也有可以独立使用.如你在示例效果图中看到的那样,每一行前两个是独立使用渐变元素的效果,后两个是讲渐变效果应用到其它元素上的