来源于微信公众号:程序员学习分享录
qml的总结 经过几天的学习,简单的了解了qml的一些基础,在此记录分享。
先说下:windows下怎么安装Qt软件【这个问题,曾经搞了我一阵子,万事开头难,这就是第一步啊】
先去官网 qt下载路径下载最新或者适合你的版本(因为你开发的东西是要给别的系统使用的,需要依赖系统的支持程度,比方说,之前认为系统也许支持QWidget,愣是看了好久的QWidget相关知识以及css的相关知识,最后放弃,选择看qml。听说:现在市面上都以qml开发为主)
其中有一步最重要的就是需要关联下载mingw和perl,这个需要自己勾选【默认是不勾选的】,
然后【下一步】就可以了。
进入正题 如果你学过js的话,那么就会简单很多
如果你学过Android的话,我会从Android的角度讲讲的
学习Qt的时候一定要知道你将要开发的系统支持的qt版本是多少,否则你用了很多新的api却在对方的平台上面运行异常,这些都是要考虑的
目前最新的qt版本是5.12 ,而我安装的是5.8的,因为目前大多数的设备都支持,一旦遇到不支持的,可能需要采取兼容的方案(即采用对方可支持的版本然后再实现)
最后记得如果遇到不懂的先看帮助文档,因为我遇到了好多本可以看下帮助文档就解决,却花在百度上面好久也没有找到方案的问题。eg:
解读:
qmake 的意思是需要在项目的pro文件中加入 “quick” 的意思 即(QT += quick),才可以支持这个控件。
Instantiated By 和 Inherits 表示实现和继承,所有的控件都是继承自QObject的(类似java的Object,而Qt里面的Item相当于Android的View和ViewGroup,是所有控件的基类)
如果需要在C++中使用这个控件需要导入include <QQuickItem> ,这一点没有Android的IDE来的好,一键导入所有的包。在Qt里面你需要老老实实的输入导入的头文件,否则你的IDE将联想不出来相关的api,当然编译会有问题的。
以下都是基于
系统:Debian9_64 ,
qt版本:5.8
qml 的布局 如果你在qml文件中,引入import QtQuick.Layouts 1.X,你可以使用的控件可以从右侧的设计板块中看到新引入的控件,一共有四个,分别是ColumnLayout,GridLayout,RowLayout,SplitView
当然可以用拖动来绘制布局,但是建议前期,还是自己学会怎么在qml文件中,编写具体的qml代码。毕竟知道qml的代码有助于你成为一个真正的界面大神,拖拽只是一种辅助而已。
说一下:Grid和GridLayout的区别,其他的布局和控件同理
GridLayout是个一堆控件的排序规则,而Grid是一个控件,这个控件里面还可以拥有控件的控件
qml的控件
import QtQuick.Controls 1.4 如果你加入这个,你就可以看到好多控件可以使用,比方说Button,Label等
简单介绍几个常用的控件
Rectangle 矩形控件 一般可以用来绘制圆角矩形,圆形还可以用作别的控件的子控件用来填充背景颜色。
Rectangle { id: rectangle2 width: 200 height: 200 color: "#ffffff" }
MouseArea 响应鼠标点击区域控件 一般用在桌面开发的控件,响应数据点击的事件,如果想用这个控件,而不知道怎么用,那么选中这个控件,然后按F1 吧,会有帮助文档的,好好理解,一点有所收获。
MouseArea { id: mouseArea width: 100 height: 100 onClicked: console.log("hello world") }
qml之listView 如果你学过Android那么你知道listview用来展示一堆数据的,可具有上下,或者左右滚动的控件。qt里面也是这样的。
先说怎么编写这个控件,然后再说怎么填充数据。
ListView { anchors.fill: parent model: 10 delegate: Text { property var item: try{ return modelData }catch(e){ return ListView.view.model.get(index); } property int age: item || item.age text:age } }
其中delegate表示适配器,就是布局需要展示的模样,这里可以加入js的代码来进行一些逻辑处理。delegate后面可以跟你想要的任何控件。 其中modelData 表示引用填充的数据,相当于在view中使用具体内容的方式。model 表示具体填充的数据。
在js中定义一个变量是var a =1 这里面是可以定义为property var a : 1 表示这个值可以通过外部进行设置。
eg:你可以通过在一个控件中声明这个变量来让外部进行赋值,相当于为一个控件增加某个属性。
// Test.qml Rectangle { id :root property var borderColor: "blue" property var borderWidth: 2 radius: width/2 border.width: borderWidth border.color: borderColor }
//Main.qml Test{ borderWidth: 10 }
接下来讲怎么讲数据绑定到视图。在Android里面可以通过适配器进行设置
介绍一种姿势:其他姿势请看参考资料
ObjectModel{ id:listModel } ListView { id: listView width: parent.width height: parent.height anchors.fill: parent model: listModel clip: true }
//动态添加视图以及数据 function recvTxzSignal(cmd,param) { com = Qt.createComponent("qrc:/qml/Usr.qml") if (com !== null) { listModel.append(com.createObject(listView,{json_data:json})) listView.positionViewAtEnd() } }
//Usr.qml Item { property var json_data: null Text{ text:getText(parent.json_data["query"]) } }
参考资料:
QML 中的 ListView 中的隐藏秘技
qml中c++来填充数据
qml之动画 可以通过查看帮助文档进行查看,切记,帮助文档很强大的。
由图中可以看出基类Animation是所有动画的基类,实现的类有方框中的Inherited By 。
PropertyAnimation 是属性动画。AnchorAnimation 是角度动画。ParallelAnimation 是异步动画,可同时执行SequentialAnimation 是同步动画,顺序执行 eg:
//表示顺序动画,先执行放大,在执行缩小,从而达到 小->大->小
property var oriChangeBegin: 0.9 property var oriChangeEnd: 0.3 SequentialAnimation { id:soundAnim loops: Animation.Infinite running: true
NumberAnimation { target: roundWave property: "scale" duration: 1000 easing.type: Easing.Linear from:oriChangeBegin to: oriChangeEnd }
NumberAnimation { target: roundWave property: "scale" duration: 1000 easing.type: Easing.Linear to:oriChangeBegin from: oriChangeEnd } }
当然还有其他动画,记得查看帮助文档。
qml之画布 和android的画布挺像,但是qt的画布,其实就是html的画布
//画个正弦 Item { id:root visible: true width: Math.PI*2 height: 2 // 振幅 property var amplitude: height/2 property var borderWidth: 2 clip: true
Canvas{ id:canvas width: parent.width height: parent.height onPaint: {
var ctx = getContext("2d"); context.reset(); ctx.lineWidth = 2; ctx.strokeStyle= "blue" var index = 0; while (index <= width) { var endY = (Math.sin(index / width * 2.0 * Math.PI) * amplitude + (height - amplitude)/2); ctx.lineTo(index, endY); index++; } ctx.stroke();
}
} }
其中var ctx = getContext("2d"); 参数就只能是2d 然后就是画画了,画圆,画方都支持也可以支持画贝塞尔曲线。
详细文档
qml与c++交互【信号,方法】 通过发信号的方式[这里给出一种方案,其他方案看参考资料]
//main.cpp QQmlApplicationEngine engine; ActiveHelper activeHelper; engine.rootContext()->setContextProperty("$ActiveHelper",&activeHelper); //将引用传递过去给qml进行绑定 engine.load(QUrl(QStringLiteral("qrc:/qml/TestFirstQml.qml")));
//TestFirstQml.qml import QtQuick 2.6 import QtQuick.Controls 1.4 ApplicationWindow { visible: true width: 800 height: 800 id:item Rectangle{ color: "red" width: 200 height: 200
MouseArea{ anchors.fill: parent onClicked: testSignal(item) } Component.onCompleted: { console.log(); item.width =20; $ActiveHelper.sig_active.connect(item.testS);// 注意这里绑定信号与槽函数,c++通过发送这个信号可以调用qml中相绑定的方法 $ActiveHelper.activeResult(item) //调用ActiveHelper中的槽函数 } signal testSignal(var anObject) } functiontestS(){ console.log("qml test"); } }
//ActiveHelper.h #ifndef ACTIVEHELPER_H #define ACTIVEHELPER_H #include <QObject>
class ActiveHelper : public QObject { Q_OBJECT public: explicit ActiveHelper(QObject *parent = 0);
/** * @brief 执行激活流程 */ void active();
/** * @brief 发送激活信号 */ void sendSigActive(){ emit sig_active(); }
signals: /** * @brief active信号 */ void sig_active();
public slots: /** * @brief 激活结果回来(可能成功,可能失败) */ void activeResult(const QVariant &); };
#endif // ACTIVEHELPER_H
//ActiveHelper.cpp #include "activehelper.h" #include "txz_common.h"
ActiveHelper::ActiveHelper(QObject *parent) : QObject(parent){}
void ActiveHelper::active() { TXZ_LOGD("active"); }
void ActiveHelper::activeResult(const QVariant &v) { TXZ_LOGD("active result"); emit sig_active(); //发送信号 }
参考资料 Interacting with QML Objects from C++
其他 间距不生效的问题
在设置相对位置间距的时候,一定要设置相对应的锚边,然后才可以设置边距
Rectangle { id: rectangle width: 200 height: 200 color: "#ffffff" anchors.right: parent.right //一定要设置这个属性,rightMargin才会生效 anchors.rightMargin: 440 }
参考资料: qt帮助文档
加载不出来界面的问题
//第一种方式:需要采用ApplicationWindow【window才可以展示】 QQmlApplicationEngine engine; ActiveHelper activeHelper; engine.rootContext()->setContextProperty("$ActiveHelper",&activeHelper); engine.load(QUrl(QStringLiteral("qrc:/qml/TestFirstQml.qml")));
//需要以Item等控件才可以展示 QQuickView view(QUrl(QStringLiteral("qrc:/qml/Test.qml"))); QQuickItem * item = view.rootObject(); view.show();
内容自适应,好像没有找到【不知道有什么方法】
参考资料:
使用gdb进行调试
---------------------------------------------------------------------------------------------------------------------- 我们尊重原创,也注重分享,文章来源于微信公众号:程序员学习分享录,建议关注公众号查看原文。如若侵权请联系qter@qter.org。 ----------------------------------------------------------------------------------------------------------------------
|