百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

初识QML-旋转的风车

bigegpt 2024-09-16 12:12 6 浏览

前言

我用Qt开发桌面程序也已经好几年,但是对QML真的算不上熟悉。首先项目中一次都没用使用过,其次之前虽然零零散散的看了一些文章和电子书,但是时间一长又忘得差不多了,所以准备重头再学习一遍,并将过程和经验分享给大家。

什么是QML?

QML是一种描述性的脚本语言,文件格式以.qml结尾。语法格式非常像CSS,但又支持javascript形式的编程控制。QtDesigner可以设计出·ui界面文件,但是不支持和Qt原生C++代码的交互。QtScript可以和Qt原生代码进行交互,但是有一个缺点,如果要在脚本中创建一个继承于QObject的图形对象非常不方便,只能在Qt代码中创建图形对象,然后从QtScript中进行访问。而QML可以在脚本里创建图形对象,并且支持各种图形特效,以及状态机等,同时又能跟Qt写的C++代码进行方便的交互,使用起来非常方便。

第一个QML程序-旋转的风车

我们通过编写一个简单的、旋转的风车来了解QML语言的某些特性。

首先我们打开Qt,新建一个Qt Quick Application。

项目新建完成以后,得到了一个默认的工程,和一个默认的main.qml文件。

此时我们先点击运行,效果如下图所示,就是一个非常简单的程序,在窗口中间显示了一条Hello World文本。

下面我们再来看一下main.qml中的代码:

  • 前面两行是导入库,相当于C++中的#include,或者Python中的import。
  • 下面的所有内容都被Window { }括起来了,我们称Window为当前这个main.qml的根元素,每个QML必须有且只能有一个根元素。
  • 至于被Window元素包含的几个元素,下面会依次讲到

再回到我们最初的目的,我们怎么把当前的这个main.qml改造成一个会旋转的风车呢?

首先我们把Window { }中包含的元素都删掉,只保留下面所示的几行代码:

再运行一下,发现并不会有窗口弹出,这是因为此时窗口不可见了,需要我们设置一下窗口可见,此时我们就需要使用visible属性,并将其设置为true,此时再运行一下,效果如下:

但是我们发现此时的窗口虽然可拉伸,但每次打开的时候都很小,而且整个窗口光秃秃的,不怎么好看,那么我们就先来改变一下窗口的大小,改变窗口大小需要使用widthheight这两个属性,顾名思义及宽和高,我们将宽设置为640px,高设置为480px,此时运行效果如下:

然后我们就来改变窗口背景,我想要用自己喜欢的一张图片覆盖整个窗口背景该怎么实现呢?

其实很简单,我们只需要在Window元素中再添加一个Image元素,然后设置Image元素的图片资源并让其覆盖整个窗口即可,代码和运行效果如下所示:

注意每一个元素都有属性,id这个特殊的属性是可选的,包含了一个特殊的标识符,在QML文档后面的地方可以直接引用。一个id属性无法在它被设置后改变,并且在程序执行期间无法被设置。

为了让图标覆盖整个窗口,我使用了一个复杂的属性anchors,可以称之为锚。锚定允许你指定一个对象与父对象或者同级对象之间的位置关系。其使用方法如下:

  • 放置在父元素中间:anchors.centerln:parent
  • 放置在父元素左边:anchors.left:parent
  • 放置在父元素右边:anchors.right:parent
  • 放置在父元素顶部:anchors.top:parent
  • 放置在父元素底部:anchors.bottom:parent
  • 填充父元素:anchors.fill:parent
  • 放置在父元素垂直中央:anchors.verticalCenter:parent
  • 放置在父元素水平中央:anchors.horizontalCenter:parent
  • 有时还需要一些微小的调整,使用anchors.horizontalCenterOffests或者anchors.verticalCenterOffest。

source属性指定Image的图片资源路径,我们需要先在项目中添加相应的资源,添加方法为:右键项目名称--添加新文件--Qt--Qt Resource File

然后点击右下角的choose,在新弹出的界面中输入资源名称即可:

添加完成以后,左侧项目树形结构的资源下面就会多出一个image.qrc的子节点,我们右击该节点选择添加现有文件,然后在打开的目录中选择自己的图片资源即可:

背景图片设置好了以后,我们就来实现风车,首先我们在背景Image元素中再添加一个新的Image子元素,id设为wheel,并设置其图片资源和居中放置,代码和效果如下:

风车图片使用的是矢量图:

到此为止,我们已经实现了风车的显示,那么怎么让其旋转呢?

想让其旋转有两种方式一个是触发式的旋转,即每次点击鼠标或按下某个按键,图片进行旋转,另一种是自动的旋转,本篇文章先讲解第一种实现方式,第二种后面的文章会介绍。

为了响应鼠标的点击,我们需要使用mouseArea元素,并让该元素的大小和我们的背景图片大小一样,及覆盖整个窗口区域。当我们点击覆盖区域时,鼠标点击区域会发出一个信号,我们可以重写onClicked函数来连接这个信号。此时我们就让风车旋转90度,代码如下:

对于每个工作的信号,命名方式都是on+SignalName,当属性的值发生改变时也会发出一个信号,它的命名方式是on+PropertyName+Changed。如果一个width属性发生了改变,我们可以用onWidthChanged:print(width)来打印出这个新的宽度值。

此时运行的动态效果如下:

现在风车虽然会旋转了,但是还不够流畅,风车的角度属性直接被改变了,整个变化令人感觉很突兀,那么我们应该怎样让每次的旋转持续一段时间呢,形成一个动态的轨迹?

这时候就该动画闪亮登场啦,一个动画定义一个属性在一段时间内的变化过程。为了实现这个效果,我们使用一个动画类型叫做属性行为。这个行为指定了一个动画来定义属性的每一次改变并赋值给属性。每次属性改变,动画都会运行。这是QML中声明动画的几种方式中的一种:

Behavior on rotation {
    NumberAnimation {
        duration: 250
    }
 }

此时我们最终的代码如下:

旋转的风车运行效果如下,动画已经很正常,轨迹也变得流畅了。

那么今天就分享到这里了,喜欢的朋友点一波关注,明天继续更新,不知不觉又是凌晨了,各位晚安、好梦。

相关推荐

最全的MySQL总结,助你向阿里“开炮”(面试题+笔记+思维图)

前言作为一名编程人员,对MySQL一定不会陌生,尤其是互联网行业,对MySQL的使用是比较多的。对于求职者来说,MySQL又是面试中一定会问到的重点,很多人拥有大厂梦,却因为MySQL败下阵来。实际上...

Redis数据库从入门到精通(redis数据库设计)

目录一、常见的非关系型数据库NOSQL分类二、了解Redis三、Redis的单节点安装教程四、Redis的常用命令1、Help帮助命令2、SET命令3、过期命令4、查找键命令5、操作键命令6、GET命...

netcore 急速接入第三方登录,不看后悔

新年新气象,趁着新年的喜庆,肝了十来天,终于发了第一版,希望大家喜欢。如果有不喜欢看文字的童鞋,可以直接看下面的地址体验一下:https://oauthlogin.net/前言此次带来得这个小项目是...

精选 30 个 C++ 面试题(含解析)(c++面试题和答案汇总)

大家好,我是柠檬哥,专注编程知识分享。欢迎关注@程序员柠檬橙,编程路上不迷路,私信发送以下关键字获取编程资源:发送1024打包下载10个G编程资源学习资料发送001获取阿里大神LeetCode...

Oracle 12c系列(一)|多租户容器数据库

作者杨禹航出品沃趣技术Oracle12.1发布至今已有多年,但国内Oracle12C的用户并不多,随着12.2在去年的发布,选择安装Oracle12c的客户量明显增加,在接下来的几年中,Or...

flutter系列之:UI layout简介(flutter-ui-nice)

简介对于一个前端框架来说,除了各个组件之外,最重要的就是将这些组件进行连接的布局了。布局的英文名叫做layout,就是用来描述如何将组件进行摆放的一个约束。在flutter中,基本上所有的对象都是wi...

Flutter 分页功能表格控件(flutter 列表)

老孟导读:前2天有读者问到是否有带分页功能的表格控件,今天分页功能的表格控件详细解析来来。PaginatedDataTablePaginatedDataTable是一个带分页功能的DataTable,...

Flutter | 使用BottomNavigationBar快速构建底部导航

平时我们在使用app时经常会看到底部导航栏,而在flutter中它的实现也较为简单.需要用到的组件:BottomNavigationBar导航栏的主体BottomNavigationBarI...

Android中的数据库和本地存储在Flutter中是怎样实现的

如何使用SharedPreferences?在Android中,你可以使用SharedPreferencesAPI来存储少量的键值对。在Flutter中,使用Shared_Pref...

Flet,一个Flutter应用的实用Python库!

▼Flet:用Python轻松构建跨平台应用!在纷繁复杂的Python框架中,Flet宛如一缕清风,为开发者带来极致的跨平台应用开发体验。它用最简单的Python代码,帮你实现移动端、桌面端...

flutter系列之:做一个图像滤镜(flutter photo)

简介很多时候,我们需要一些特效功能,比如给图片做个滤镜什么的,如果是h5页面,那么我们可以很容易的通过css滤镜来实现这个功能。那么如果在flutter中,如果要实现这样的滤镜功能应该怎么处理呢?一起...

flutter软件开发笔记20-flutter web开发

flutterweb开发优势比较多,采用统一的语言,就能开发不同类型的软件,在web开发中,特别是后台式软件中,相比传统的html5开发,更高效,有点像c++编程的方式,把web设计出来了。一...

Flutter实战-请求封装(五)之设置抓包Proxy

用了两年的flutter,有了一些心得,不虚头巴脑,只求实战有用,以供学习或使用flutter的小伙伴参考,学习尚浅,如有不正确的地方还望各路大神指正,以免误人子弟,在此拜谢~(原创不易,转发请标注来...

为什么不在 Flutter 中使用全局变量来管理状态

我相信没有人用全局变量来管理Flutter应用程序的状态。毫无疑问,我们的Flutter应用程序需要状态管理包或Flutter的基本小部件(例如InheritedWidget或St...

Flutter 攻略(Dart基本数据类型,变量 整理 2)

代码运行从main方法开始voidmain(){print("hellodart");}变量与常量var声明变量未初始化变量为nullvarc;//未初始化print(c)...