QtQuick大杂烩

来源:互联网 发布:万网域名续费 编辑:程序博客网 时间:2024/05/19 08:44
一、基本可视元素
1、Item
QML中所有的可视项目都继承自Item,Item本身没有可视化的外观,但它定义了可视化项目的所有属性。可作容器
x, y, width, height, anchors, Keys, visible, opacity(是一个继承属性,会应用到子项目上),z
childAt(real x, real y), mapFromItem(Item item,real x,real y), mapToItem(Item item,real x,real y)...
eg:
Item{
    Image{ source: "tile.png" }
    Image{ x: 80; height: 100; width: 100; source: "tile.png" }
    Image{ x: 190; height: 100; width: 100; fillMode: Image.Tile; source: "tile.png" }
}   //Item作容器
Item{
    children: [
        Text{},
        Rectangle{}
    ]
    resources: [
        Timer{}
    ]
}  //children属性包含可见的孩子列表,resources包含了不可见的资源
//Item中有一个data默认属性,允许可见不可见元素自由混合,若可见,则作为孩子;否则,作为资源。
2、Rectangle
Rectangle使用纯色或渐变来填充一个区域,若都指定,使用gradient。
color, gradient属性指定一个Gradient元素定义的渐变来填充,
添加一个可选的边界,并使用border.color, border.width, radius, smooth(渲染代价),
3、Text
一个Text项目可以显示纯文本或者富文本。
eg:
Column{
    Text{
        width: 200;
        font.family: "Helvetica"
        font.pointSize: 24
        font.bold: true
        font.capitalization: Font.AllUppercase
        font.letterSpacing: 2 //-2
        font.strickout: false
        font.underline: true
        font.wordSpacing: 3
        text: "Hello"
        style: Text.Raised //Text.Normal, Text.Outline, Text.Sunken
        color: "red"
        elide: Text.ElideMiddle
        // wrapMode: Text.WordWrap  //自动换行,必须指定width属性时才起作用
        horizontalAlignment: Text.AlignHCenter
        verticalAlignment: Text.AlignVCenter
    }
    Text{
        text: "<b>Hello</b> <i>World</i>"
    }
    FontLoader{ id: fixedFont; name "Courier" }
    FontLoader{ id: webFont; source: "http://www.mysite.com/myfont.ttf" }
    Text{ text: "Fixed-size font"; font.family: fixedFont.name }
    Text{ text: "Fancy font"; font.family: webFont.name }
    Text{
        textFormat: Text.RichText
        text: "The main website is at < a href = \"http://qt.nokia.com\" > Nokia Qt DF </a>."
        onLinkActivated: console.log(link + "link activated")
    }
}
4、TextEdit
TextEdit没有提供滚动、光标跟随或其他行为,通常使用Flickable元素来提供滚动实现光标跟随:
import QtQuick 2.3
Flickable{
    id: flick
    width: 300; height: 200;
    contentWidth: edit.paintedWidth
    contentHeight: edit.paintedHeight
    clip: true
    function ensureVisible(r){
        if(contentX > r.x)
            contentX = r.x;
        else if(contentX + width <= r.x + r.width)
            contentX = r.x + r.width - width;
        if(contentY <= r.y)
            contentY = r.y
        else if(contentY + height <= r.y + r.height)
            contentY = r.y + r.height - heigth;
    }
    TextEdit{
        id: edit
        width: flick.width
        height: flick.height
        focus: true
        color: "lightgreen"
        wrapMode: TextEdit.Wrap
        onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
    }
}
TextEdit通过cut()、copy()和paste()等函数提供了对剪贴板的支持。
设置selectByMouse属性可以启用鼠标选取内容;也可用QML代码来完成内容的选取,这需要设置selectionStart和selectionEnd,
然后使用selectAll()或selectWord()函数进行操作。
openSoftwareInputPanel()和closeSoftwareInputPanel()函数分别在特定的设备上打开和关闭软件盘。
5、TextInput元素用来显示单行的可编辑纯文本。
eg:
TextInput{
    validator: IntValidator{    //DoubleValidator, RegExpValidator
        bottom: 11; top: 31;   //只能输入11——31之间的整数
    }
    echoMode: TextInput.Password  //密码显示
    focus: true
}
二、事件处理
1、在QML中如果一个项目想要能够被单击,就要在其上放置一个MouseArea元素。
MouseArea的enabled属性设置是否启用鼠标处理,默认true;只读属性pressed表明是否在MouseArea按住了鼠标;
只读的containsMouse属性表明当前是否有鼠标光标在MouseArea上,默认鼠标一个按钮按下才检测到。
onClicked(), onDoubleClicked(), onPressed(), onReleased(), onPressAndHold()等
默认不报告光标的位置改变,可通过hoverEnabled属性进行修改,then:
onPositionChanged(), onEntered(), onExited()可使用;containsMouse属性也可以在鼠标没有按下时进行检查。
eg:
Rectangle{
    width: 100; height: 100
    color: "green"
    MouseArea{
        anchors.fill: parent
        coClicked: { parent.color = "red" }
    }
}
在MosueEvent中,可通过x,y获取鼠标位置;通过button属性获得按下的按键;通过modifier属性获得按下的键盘修饰符,
再使用时需要将modifiers与这些特殊的按键进行按位与来判断按键。
button可能取值:Qt.LeftButton, Qt.RightButton, Qt.MiddleButton
modifier可能取值:Qt.NoModifier, Qt.ShiftModifier, Qt.ControlModifier, Qt.AltModifier
eg:
Rectangle{
    width: 100; height: 100
    color: "green"
    MouseArea{
        anchors.fill: parent
        acceptedButtons: Qt.LeftButton | Qt.RightButton
        onClicked: {
            if(mouse.button == Qt.RightButton)
                parent.color = "blue"
            else if((mouse.button == Qt.LeftButton)
                    && (mouse.modifiers & Qt.ShiftModifier))
                parent.color = "green"
            else
                parent.color = "red"
        }
    }
}
2、拖拽:
MouseArea中的drag分组属性提供了可使一个项目可拖拽的简便方法。
drag.target属性指定拖动的项目id
drag.active属性获取项目是否被拖动
drag.axis属性指定拖动方向:Drag.XAxis, Drag.YAxis, Drag.XAndYAxis
drag.minimum和drag.maximum限制在指定方向上的拖动距离
eg:
Rectangle{
    id: container
    width: 600; height: 200
    Rectangle{
        id: rect
        width: 50; height: 50
        color: "red"
        opacity: (600.0 - rect.x)/600  //透明度随拖动位置而变
        MouseArea{
            anchors.fill: parent
            drag.target: rect
            drag.axis: Drag.XAxis
            drag.minimumX: 0
            drag.maximumX: container.width - rect.width
        }
    }
}
3、键盘按键处理
按下或释放一个按键,会以如下步骤进行处理:
一、Qt获取键盘动作并产生一个键盘事件
二、如果高寒QDeclarativeView的Qt部件具有焦点,那么键盘事件会传递给它
三、场景将键盘事件交付给具有活动焦点的QML项目
四、若三接收了,传播停止,否则该事件会递归的传递到每一个项目的父项目,直到被接受或到达根项目
1、所有基于Item的可见元素都可以通过Keys附加属性来进行按键处理,Keys提供了基本的处理器,如: onPressed,onReleased ,
    也提供了对特殊按键的处理器,如:onCancelPressed.
eg:
Rectangle{
    width: 100; height: 100
    focus: true
    Keys.onPressed:{
        if(event.key == Qt.Key_A){
            console.log("Key A was pressed");
            event.accepted = true   //防止事件向上层项目传播
        }
    }
}
QML中还有一个KeyNavigation元素,用来实现使用方向键或Tab键来进行项目的导航,属性有backtab、up、down、
left、right、tab、priority等
eg:
import QtQuick 2.3
Grid{
    width: 100; height: 100
    columns: 2
    Rectangle{
        id: topLeft
        width: 50; height: 50
        color: focus ? "red" : "lightgray"
        focus: true
        KeyNavigation.right: topRight
        KeyNavigation.down: bottomLeft
    }
    Rectangle{
        id: topRight
        width: 50; height: 50
        color: focus ? "red" : "lightgray"
        KeyNavigation.left: topLeft
        KeyNavigation.down: bottomRight
    }
    Rectangle{
        id: bottomLeft
        width: 50; height: 50
        color: focus ? "red" : "lightgray"
        KeyNavigation.right: bottomRight
        KeyNavigation.up: topLeft
    }
    Rectangle{
        id: bottomRight
        width: 50; height:  50
        color: focus ? "red" : "lightgray"
        KeyNavigation.left: bottomLeft
        KeyNavigation.up: topRight
    }
}
2、查询一个项目是否具有活动焦点,通过Item::activeFocus属性进行查询
Text{
    text: activeFocus ? "I hava active focus" : "I do not have"
}
3、
当作为一个可重用或可被导入的组件时,简单的使用focus属性就不再有效。
eg:
//MyWidget.qml
import QtQuick 2.3
Rectangle{
    id: widget
    color: "lightsteelblue";
    width: 175; height: 25; radius: 10; smooth: true
    focus: true
    Text{ id: lable; anchors.centerIn: parent }
    Keys.onPressed: {
        if(event.key == Qt.Key_A)
            label.text = "Key A was pressed"
        else if(event.key == Qt.Key_B)
            label.text = "Key B was pressed"
        else if(event.key == Qt.Key_C)
            label.text = "Key C was pressed"
    }
}
//window.qml
Rectangle{
    id: window
    color: "white"; width: 240; height: 150
    Column{
        anchors.centerIn: parent; spacing: 15
        MyWidget{
            focus: true
            color: "lightblue"
        }
        MyWidget{
            color: "palegreen"
        }
    }
}
我希望第一个MyWidget获得焦点,但结果是第二个对象获得了焦点。
问题:window组件和两个MyWidget都设置了焦点,只能有一个元素可获得焦点,因为window中第二个MyWidget
是最后一个设置focus为true的元素,所以它获得焦点。第一个MyWidget组件希望获得焦点,但当它被导入或被重用后
就无法控制焦点,也就是说,window组件无法知道它导入的组件是否请求了焦点。
为解决这个问题,QML引入焦点作用域(FocusScope)。
//新的的MyWidget.qml组件
import QtQuick 2.3
FocusScope{             //FocusScope不可见
    property alias color: rectangle.color
    x: rectangle.x; y: rectangle.y //将子项目的属性绑定到FocusScope上,若不绑定,column将不能正常显示
    Rectangle{
        id: rectangle
        anchors.centerIn: parent
        color: "lightsteelblue";
        width: 175; height: 25; radius: 10; smooth: true
        Text{ id: label; anchors.centerIn: parent }
        focus: true
        Keys.onPressed: {
            if(event.key == Qt.Key_A)
                label.text = "Key A was pressed"
            else if(event.key == Qt.Key_B)
                label.text = "Key B was pressed"
            else if(event.key == Qt.Key_C)
                label.text = "Key C was pressed"
        }
    }
}
4、定时器
eg:
import QtQuick 2.3
Item{
    Timer{
        interval: 500;
        running: true; repeat: true  //若repeat设为false,触发一次后running自动为false
        onTriggered: time.text = Date().toString()
    }
    Text{ id: time }
}
三、使用Loader动态加载组件
1、Loader元素用来动态加载可见的QML组件,可以加载一个QML文件(source)或一个组件对象(sourceComponent)。
eg:
Item{
    width: 200; height: 200
    Loader{ id: pageLoader }
    MouseArea{
        anchors.fill: parent
        onClicked: pageLoader.source = "Page.qml"
    }
}
如果source或sourceComponent更改了,任何先前实例化的项目都将被销毁。将source设置为空字符串或将sourceComponent
设置为undefined,则销毁当前加载的项目,释放资源并且将Loader设置为空。
必须对Loader进行位置和大小的设置,若没明确指定Loader的大小,那么Loader将会在组件加载完成后自动设置为组件的大小;
若通过width、height或使用锚明确指定了Loader大小,则被加载的项目会变为Loader的大小。
2、从加载的项目中接收信号
任何从被加载的项目中发射的信号都可以使用Connections元素进行接收。
eg:
//application.qml
import QtQuick 2.3
Item{
    width: 100; height: 100
    Loader{
        id: myLoader
        source: "MyItem.qml"
    }
    Connections{
        target: myLoader.item
        onMessage: console.log(msg)
    }
}
//MyItem.qml
Rectangle{
    id: myItem
    signal message(string msg)
    width: 100; height: 100
    MouseArea{
        anchors.fill: parent
        onClicked: myItem.message("Clicked")
    }
}
3、焦点和键盘事件
Loader是一个焦点作用域,对于它的任何获得活动焦点的子项目都必须将forcus属性设置为true,任何在被加载的项目中的
键盘事件也应该被接受,从而使他们不传播到Loader。
eg:
//application.qml
import QtQuick 2.3
Rectangle{
    width: 200; height: 200
    Loader{
        id: loader
        focus: true
    }
    MouseArea{
        anchors.fill: parent
        onClicked: loader.source = "KeyReader.qml" 
    } //若没击鼠标,直接敲键盘输出的是"Captrued:..."
    Keys.onPressed: {
        console.log("Captured: " , event.text) //若击鼠标没有被输出,因为没有向上传递
    }
}
//KeyReader.qml
import QtQuick 2.3
Item{
    Item{
        focus: true
        Keys.onPressed: {
            console.log("Loaded item captured:", event.text)
            event.accepted = true
        }
    }
}
                                             
0 0
原创粉丝点击