QML 界面与逻辑分离 Timer的onTiriggered访问不到导出的QML控件变量处理,Canvas自定义QML变量实线可直接使用的代码
网上有很多处理但都是UI和逻辑混用在一个QML里面,现在项UI和逻辑分开处理的。
1.编写canvas自定义QML控件 YxForm.qml
import QtQuick 2.4
import QtQuick.Controls 2.4
Item {
id: yx
width: 120
height: 240
property color bordercolor: Qt.rgba(0.1,0.1,0.1,1.0)
property color forecolor: Qt.rgba(0,1.0,0,1.0)
property color forecolorlow: Qt.rgba(1,1,0.3,1.0)
property color forecolorover: Qt.rgba(1,0.3,0.3,1.0)
property var fMax: 120
property var fMin: 0
property var fUpLimit: 100
property var fDownLimit: 60
property var fVal: 80
onFValChanged: {
console.log("1111111111111:"+fVal.toString())
yxCanvas.requestPaint()
}
// 其他触发界面刷新的事件
Canvas {
id: yxCanvas
width: yx.width
height: yx.height
onPaint: {
var ctx = getContext("2d")
ctx.clearRect(0,0,width,height)
ctx.font="16px 宋体"
var lineUplimitH = height/10.0*3;
var lineDownLimitH = height/10.0*8;
// 背景
if(yx.fVal > yx.fUpLimit){
ctx.save();
ctx.fillStyle=forecolorover
var nhh = (yx.fVal-yx.fUpLimit) / (yx.fMax-yx.fUpLimit)
if(nhh > 1){
nhh = lineUplimitH;
}else{
nhh = nhh *lineUplimitH;
}
ctx.fillRect(2,lineUplimitH-nhh,width-4,nhh+height-lineUplimitH);
ctx.restore();
}else if(yx.fVal > yx.fDownLimit){
ctx.save();
ctx.fillStyle=yx.forecolor
var fTotalH = lineDownLimitH-lineUplimitH
var downH = height - lineDownLimitH
var fhh = (yx.fVal-yx.fDownLimit) / (yx.fUpLimit-yx.fDownLimit)
if(fhh >= 1){
fhh = fTotalH;
}else{
fhh = fhh *fTotalH;
}
ctx.fillRect(2,lineUplimitH+fTotalH-fhh,width-4,fhh+downH);
ctx.restore();
}else{
ctx.save();
ctx.fillStyle=forecolorlow
var fdownH = height - lineDownLimitH
var fhh1 = yx.fVal /yx.fDownLimit
if(fhh1 >= 1){
fhh1 = fdownH;
}else{
fhh1 = fhh1 *fdownH;
}
ctx.fillRect(2,lineDownLimitH+fdownH-fhh1,width-4,fhh1);
ctx.restore();
}
// 画上下限线
ctx.save();
ctx.lineWidth = 1
ctx.strokeStyle = bordercolor
ctx.strokeRect(0,0,width,height)
ctx.beginPath()
ctx.moveTo(0,lineUplimitH)
ctx.lineTo(width,lineUplimitH)
// 单个实线的长度-5和虚线的长度-8
ctx.setLineDash([5,2])
ctx.stroke()
ctx.beginPath()
ctx.moveTo(0,lineDownLimitH)
ctx.lineTo(width,lineDownLimitH)
ctx.stroke()
ctx.restore();
// 写文字
ctx.save();
ctx.textAlign = "left";
ctx.textBaseline = "bottom";
ctx.fillText(yx.fUpLimit.toString(), 3, lineUplimitH-2);
ctx.fillText(yx.fDownLimit.toString(), 3, lineDownLimitH-2);
ctx.restore();
if(lineUplimitH > 30){
ctx.save();
ctx.fillStyle=Qt.rgba(0.8,0.8,0.5,1.0)
ctx.fillRect(2,2,width-4,32);
ctx.restore();
ctx.save();
ctx.textAlign = "center"; // 设置文本水平居中
ctx.textBaseline = "middle"; // 设置文本垂直居中
ctx.fillText(yx.fVal.toString(), width /2, 32/2);
ctx.restore();
}
}
}
}
自定义界面的访问
Page2Form.ui.qml
定义并导出UI变量
property alias yyxx1: yyxx1
property alias yyxx: yyxx
YxForm {
id: yyxx
anchors.top: column2.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.leftMargin: parent.width/6
width: 150
}
YxForm {
id: yyxx1
anchors.top: column2.bottom
anchors.bottom: parent.bottom
anchors.left: yyxx.right
anchors.leftMargin: parent.width/3
width: 100
}
效果

在QML中需要动态改变实际进度值
Page2Form {
Component.onCompleted: {
timer1.start()
}
function updateyx(){
yyxx.fVal = yyxx.fVal+10;
yyxx1.fVal = yyxx1.fVal+3;
if(yyxx.fVal > 120){
yyxx.fVal = 1;
}
if(yyxx1.fVal > 120){
yyxx1.fVal = 1;
}
}
Timer{
id: timer2
interval: 1000
running: false
repeat: true
onTriggered: {
updateyx();
}
}
}
此时访问不到 updateyx() 错误显示 ReferenceError: updateyx is not defined
修改一下直接访问对象看看
Timer{
id: timer2
interval: 1000
running: false
repeat: true
onTriggered: {
yyxx.fVal = yyxx.fVal+10;
}
}
结果: ReferenceError: yyxx is not defined
解决方案:把onTriggered函数直接connect到本对象的函数上就可以了,类似于
Page2Form {
Component.onCompleted: {
timer1.onTriggered.connect(updateyx )
timer1.start()
}
function updateyx(){
yyxx.fVal = yyxx.fVal+10;
yyxx1.fVal = yyxx1.fVal+3;
if(yyxx.fVal > 120){
yyxx.fVal = 1;
}
if(yyxx1.fVal > 120){
yyxx1.fVal = 1;
}
}
Timer {
id: timer1
interval: 1000
running: false
repeat: true
}
}
此时可以看到修改UI对象属性,并更新UI,生效了,效果


360

被折叠的 条评论
为什么被折叠?



