继QML2.0TabView之后,打算简单说下PathView这个QML视图,最近找到先前研究的项目,但是对于PathView这个在qml2.0里面继续出现的旧东西,感觉好熟悉,看看qml2.0是否新增了一些特性或者修复了哪些bug,遂研究了下。
Properties
cacheItemCount : int
count : int
currentIndex : int
currentItem : Item
delegate : Component
dragMargin : real
dragging : bool
flickDeceleration : real
flicking : bool
highlight : Component
highlightItem : Item
highlightMoveDuration : int
highlightRangeMode : enumeration
interactive : bool
maximumFlickVelocity : real
model : model
moving : bool
offset : real
path : Path
pathItemCount : int
preferredHighlightBegin : real
preferredHighlightEnd : real
snapMode : enumeration
Attached Properties
isCurrentItem : bool
onPath : bool
view : PathView
Signals
dragEnded()
dragStarted()
flickEnded()
flickStarted()
movementEnded()
movementStarted()
Methods
decrementCurrentIndex()
incrementCurrentIndex()
int indexAt(int x, int y)
Item itemAt(int x, int y)
positionViewAtIndex(int index, PositionMode mode)
个人比较喜欢C++与QML混合编程,应该纯QML可能对于数据处理部分很是吃力,所以部分数据处理放置C++,这样是比较好,UI都是QML来实现
看下C++部分代码:
widget.h部分
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
QDeclarativeView* lolView;
QGraphicsObject* lolObj;
QParallelAnimationGroup* qrGroup;
QString lolJson;
void showQMLView();
QString pingzhuangJson(QList);
void showAnimation();
QList getFileName(QString str);
public slots:
void slotClose(QVariant,int);
void slotQrFinishedAnimation();
};
#endif // WIDGET_H
#include "widget.h"
#include
#include
Widget::Widget(QWidget *parent)
: QWidget(parent),lolView(NULL)
{
QList lst=getFileName("./qml/CoverFlowQuickApp/lol/");
lolJson = pingzhuangJson(lst);
}
Widget::~Widget()
{
}
void Widget::showQMLView()
{
if(NULL==lolView){
qDebug() << "hello in Show Log view1";
lolView = new QDeclarativeView(0);
lolView->setMinimumSize(QSize(1320,800));
lolView->setSource(QUrl("qrc:qml/CoverFlowQuickApp/main.qml"));
lolView->setWindowFlags(Qt::FramelessWindowHint);
lolView->setAttribute(Qt::WA_TranslucentBackground);
lolView->setStyleSheet("background:transparent;");
lolView->setWindowTitle(QString::fromUtf8("LOL客户端"));
lolObj = lolView->rootObject();
connect(lolObj,SIGNAL(signalsendClose(QVariant,int)),this,SLOT(slotClose(QVariant,int)));
}
QMetaObject::invokeMethod(lolView->rootObject(),"getJsonfromWidget",
Q_ARG(QVariant,QVariant::fromValue(lolJson)));
lolView->move(((QApplication::desktop()->width()/2)-(lolView->width()/2)),((QApplication::desktop()->height()/2)-(lolView->height()/2)));
lolView->show();
}
QString Widget::pingzhuangJson(QList lst)
{
QString strJson ="{\"response\":100,\"message\":\"xxxxxx\",\"data\":{\"lolinfo\":{\"lol_info\":[";
for(int i=0;i Widget::getFileName(QString str){
//"./qml/CoverFlowQuickApp/lol/
QString root = str;
QDir rootDir(root);
QStringList strings;
strings << "*.png" ;
QStringList fileList;
QString fileListName;
QList listVetor;
QFile file("./lol.txt");
QFileInfoList list = rootDir.entryInfoList(strings);
for(int i=0;isetDuration(1000);
animation2->setStartValue(QSize(this->width(),this->height()));
animation2->setEndValue(QSize(0,0));
QPropertyAnimation *animation4 = new QPropertyAnimation(lolView, "windowOpacity");
animation4->setDuration(800);
animation4->setStartValue(1.0);
animation4->setEndValue(0.0);
animation2->setEasingCurve(QEasingCurve::OutCubic);
animation4->setEasingCurve(QEasingCurve::OutCubic);
qrGroup->addAnimation(animation2);
qrGroup->addAnimation(animation4);
qrGroup->start();
}
void Widget::slotQrFinishedAnimation()
{
qApp->quit();
}
void Widget::slotClose(QVariant var,int iType)
{
int localx;
int localy;
qDebug()<<""<x();
localy = lolView->y();
lolView->move(localx + lst.at(0).toInt(), localy+lst.at(1).toInt());
}
}else{
showAnimation();
// qApp->quit();
}
}
再来看下QML部分
import QtQuick 1.1
Item {
width: 120*11; height: 800
signal signalsendClose(variant strclose,int iType)
ListModel {
id: appModel
// ListElement { name: "弗力贝尔"; icon: "lol/Volibear_Square_0.png" }
// ListElement { name: "沃里克"; icon: "lol/Warwick_Square_0.png" }
// ListElement { name: "齐勒斯"; icon: "lol/Xerath_Square_0.png" }
// ListElement { name: "XinZhao_Square_0"; icon: "lol/XinZhao_Square_0.png" }
// ListElement { name: "Yorick_Square_0"; icon: "lol/Yorick_Square_0.png" }
// ListElement { name: "Ziggs_Square_0"; icon: "lol/Ziggs_Square_0.png" }
// ListElement { name: "Zilean_Square_0"; icon: "lol/Zilean_Square_0.png" }
// ListElement { name: "Zyra_Square_0"; icon: "lol/Zyra_Square_0.png" }
// ListElement { name: "Nidalee_Square_0"; icon: "lol/Nidalee_Square_0.png" }
// ListElement { name: "Nocturne_Square_0"; icon: "lol/Nocturne_Square_0.png" }
// ListElement { name: "Nunu_Square_0"; icon: "lol/Nunu_Square_0.png" }
// ListElement { name: "Olaf_Square_0"; icon: "lol/Olaf_Square_0.png" }
// ListElement { name: "Fiddlesticks_Square_0"; icon: "lol/Fiddlesticks_Square_0.png" }
// ListElement { name: "Fiora_Square_0"; icon: "lol/Fiora_Square_0.png" }
// ListElement { name: "Fizz_square_0"; icon: "lol/Fizz_square_0.png" }
// ListElement { name: "Galio_Square_0"; icon: "lol/Galio_Square_0.png" }
}
// property XmlListModel tmpModel;
// XmlListModel {
// id: xmlModel
// source:"qrc:/qml/CoverFlowQuickApp/pics/lol.xml"
// query: "/lol/lolel/File"
// XmlRole { name: "fileName"; query: "fileName/string()" }
// XmlRole { name: "filePng"; query: "filePng/string()" }
// Component.onCompleted: {
// console.log("kasjkashjkashkahksj "+query.toString())
// tmpModel = xmlModel;
// }
// }
Item{
id: myText
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: 30
Text {
id: myText1
text: "当前为 -1"
anchors.centerIn: parent
font.bold: true
font.pixelSize: 20
font.family: "微软雅黑"
}
}
CoverFlow {
listModel: appModel
width: parent.width
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: myText.top
onIndexChanged: {
myText1.text = "当前为: " + index
}
itemWidth: 120
itemHeight: 120
color: "black"
}
Image {
source: "lol/close.png"
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 10
MouseArea {
anchors.fill: parent
onClicked: signalsendClose([""],1);
}
}
MouseArea
{
id: backmove
height: 200
anchors{
left: parent.left
right: parent.right
rightMargin: 100
top:parent.top
}
acceptedButtons: Qt.LeftButton
property int ix:0
property int iy:0
onPressed:
{
backmove.ix = mouseX;
backmove.iy = mouseY;
}
onPositionChanged:
{
var dyx = mouseX - backmove.ix;
var dyy = mouseY - backmove.iy;
var paralist = [dyx,dyy]
//paralist si windows move offset
signalsendClose(paralist,0)
}
}
function getJsonfromWidget(str){
console.log("str "+str);
var jsonObject = eval('(' + str + ')');
var resultDataObj = jsonObject.data.lolinfo.lol_info;
var response = jsonObject.response;
console.log("refresh data : "+response+" "+resultDataObj[0].icon)
for(var i =0;i<16;i++)
{
if(typeof resultDataObj[i] == "object")
console.log("refresh: "+resultDataObj[i].name)
appModel.append(resultDataObj[i]);
}
}
}
import QtQuick 1.0
Rectangle {
id: coverFlow
property int itemWidth: 120*listModel.count
property int itemHeight: 120*listModel.count
property ListModel listModel
property int angleValue: 60
signal indexChanged(string index)
gradient: Gradient {
GradientStop { position: 0.0; color: "black" }
GradientStop { position: 0.5; color: "gray" }
GradientStop { position: 1.0; color: "black" }
}
Component {
id: appDelegate
Flipable {
id: myFlipable
property bool flipped: false
property real rotationAngle: PathView.angle
width: itemWidth; height: itemHeight
z: PathView.z
scale: PathView.iconScale
function itemClicked()
{
if(PathView.isCurrentItem) {
//myFlipable.flipped = !myFlipable.flipped
myPathView.interactive = !myFlipable.flipped
}
else if(myPathView.interactive) {
myPathView.currentIndex = index;
console.log("sljaslfajlfjal")
}
}
Keys.onReturnPressed: itemClicked()
MouseArea {
anchors.fill: parent
onClicked: itemClicked()
}
transform: Rotation {
id: rotation
origin.x: myFlipable.width/2
origin.y: myFlipable.height/2
axis.x: 0; axis.y: 1; axis.z: 0
angle: rotationAngle
}
states: State {
name: "back"
PropertyChanges { target: rotation; angle: 180 }
PropertyChanges {target: myFlipable; width: myPathView.width; height: myPathView.height }
when: myFlipable.flipped
}
transitions: Transition {
ParallelAnimation {
NumberAnimation { target: rotation; property: "angle"; duration: 250 }
NumberAnimation {target: myFlipable; properties: "height,width"; duration: 250}
}
}
front: CoverItem{
id:items
width: itemWidth
height: itemHeight*2
onSignalClickeItem: {
console.log("skajfkajffafaf "+iIndex+ " icon "+iconString);
backs.curImg = iconString;
animationx.stop();
animationx.start();
}
}
// back:
}
}
CoverBackItem{
id:backs
// width: itemWidth*2
// height: itemHeight*2
opacity: 0.0
z:100
anchors.centerIn: parent
}
SequentialAnimation {
id:animationx
NumberAnimation { target: backs; property: "opacity"; to: 1; duration: 500;easing.type: Easing.InQuad }
PauseAnimation { duration: 500 }
NumberAnimation { target: backs; property: "opacity"; to: 0; duration: 500;easing.type: Easing.InQuad }
}
PathView {
id: myPathView
Keys.onRightPressed: if (!moving && interactive) incrementCurrentIndex()
Keys.onLeftPressed: if (!moving && interactive) decrementCurrentIndex()
anchors.fill: parent
preferredHighlightBegin: 0.5
preferredHighlightEnd: 0.5
focus: true
interactive: true
model: listModel
delegate: appDelegate
path: Path {
startX: 0
startY: coverFlow.height / 2
PathAttribute { name: "z"; value: 100 }
PathAttribute { name: "angle"; value: angleValue }
PathAttribute { name: "iconScale"; value: 1.0 }
PathLine { x: coverFlow.width / 2; y: coverFlow.height / 2; }
PathAttribute { name: "z"; value: 0 }
PathAttribute { name: "angle"; value: 0 }
PathAttribute { name: "iconScale"; value: 0.7 }
PathLine { x: coverFlow.width; y: coverFlow.height / 2; }
PathAttribute { name: "z"; value: 100 }
PathAttribute { name: "angle"; value: -angleValue }
PathAttribute { name: "iconScale"; value: 1.0 }
}
}
Item{
id: myText3
anchors.top: parent.top
anchors.topMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: 30
Text {
id: myText4
text: "英雄联盟-英雄抉择"
anchors.centerIn: parent
font.bold: true
font.pixelSize: 18
font.family: "微软雅黑"
color: "red"
}
}
Component.onCompleted: {
myPathView.currentIndexChanged.connect(function(){
//indexChanged(myPathView.currentIndex);
indexChanged(listModel.get(myPathView.currentIndex).name);
})
}
}
SourceCode