1.效果
想要使用QML实现滚动Text的效果,即“能够逐条上下滚动,当每条内容超过Text显示的长度时,鼠标移至上去时,能够左右滚动”;
2.实现思路
- 上下滚动:实际上使用ListView控件,只让该控件显示一行,每次更改当前的item即可,然后在更换当前item的时候添加动画即可。当移至最后一行时,可以先将第一行移至最后一行,再更换当前item,这样就避免了移到最后出现空白的情况。
- 左右移动:在Text的x方向添加动画即可。
3.QML实现代码
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0
Rectangle {
id: root;
implicitHeight: 32;
implicitWidth: 200;
signal sigAdvertisingClicked();
signal sigAdvertisingEntered();
signal sigAdvertisingExited();
property alias modelRoll: list.model;
ListView {
id: list;
objectName: "list_ads";
height: parent.height;
width: parent.width;
model: 5;
delegate: rollDelegate;
clip: true;
interactive: false;
NumberAnimation {
id: animation;
target: list;
property: "contentY";
duration: 1000;
}
}
function nextAds() {
if (list.count == 1)
return;
list.forceLayout();
var nextindex = list.currentIndex + 1;
console.log("curindex="+list.currentIndex + ",nextindex=" + nextindex);
var curpos = list.contentY;
var nextpos = curpos + 32;
list.positionViewAtIndex(nextindex, ListView.Contain);
list.currentIndex = nextindex;
animation.from = curpos;
animation.to = nextpos;
animation.running = true;
}
Component {
id: rollDelegate
Rectangle {
height: root.height;
width: root.width;
Text {
id: text_ads;
height: parent.height;
width: parent.width;
elide: Text.ElideRight;
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
font.family: nimoobs_main_window.font.family
color: "#505050"
font.pixelSize: 10;
text: '<html></style><font color="#505050"><a href="https://www-dev.nimo.tv/?_pop=1">' + list.model.get(index, 0) + '</a></font></html>'
SequentialAnimation on x {
loops: 0;
id: seq_ads_x;
PropertyAnimation {
from: 0
to: -(text_ads.contentWidth - text_ads.width)
duration: 3000
}
onStopped: {
if (text_ads.x == (-(text_ads.contentWidth - text_ads.width))) {
} else {
}
}
}
MouseArea {
anchors.fill: parent
cursorShape: entered ? Qt.PointingHandCursor : Qt.ArrowCursor;
hoverEnabled: true
onEntered: {
text_ads.elide = Text.ElideNone;
if (text_ads.contentWidth > text_ads.width) {
seq_ads_x.loops = 1;
seq_ads_x.running = true;
}
emit: sigAdvertisingEntered();
}
onExited: {
seq_ads_x.running = false;
text_ads.x = 0;
text_ads.elide = Text.ElideRight;
emit: sigAdvertisingExited();
}
onClicked: {
seq_ads_x.running = false;
text_ads.x = 0;
emit: sigAdvertisingClicked();
}
}
}
}
}
}
小猫咪