在QML中,原生的Label是不能够进行鼠标的选中,复制,全选等操作的,仅仅只能用于简单的展示文字,但是在实际开发中,往往我们需要给用户展示一些信息,而且要支持可以用鼠标进行选择文字,并进行复制操作,所以,用QML中的Label控件显然是不行的,因此考虑重写控件实现以上功能:
import QtQuick 2.2
import QtQuick.Controls 1.2
Rectangle {
id: root
width: 300
height: 300
Label {
id: lab_name
anchors{
left: parent.left
leftMargin: 30
top: parent.top
topMargin: 50
}
font.pixelSize: 16
text: "姓名:"
}
TextArea {
id: lbl_name_show
anchors{
left:lab_name.right
top:lab_name.top
}
verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff
implicitHeight: lab_name.height
antialiasing: true
readOnly: true
frameVisible : false
backgroundVisible : false
contentItem : TextArea{
id: lab_txt
text:"三个程序员"
readOnly: true
font.pixelSize: 16
anchors.bottom: parent.bottom
anchors.bottomMargin: 4
frameVisible : false
backgroundVisible : false
}
MouseArea {
id: mouse_area
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.MiddleButton
onEntered: {
tool_tip.text = lab_txt.text
tool_tip.onVisibleStatus(true)
}
onExited: {
tool_tip.text = ""
tool_tip.onVisibleStatus(false)
}
onPositionChanged: {
tool_tip.mouserHover(lbl_name_show, mouseX, mouseY)
}
}
visible: true
}
Tooltip {
id: tool_tip
}
}
以上就是实现对
Label功能的重写,以实现信息的展示、选中文字,选中复制和全选等右键操作与键盘快捷键ctrl+c复制操作,可以看出,其实是利用了QML的TextArea 的本身右键功能,但是TextArea 是有边框背景等属性的,所以去掉了TextArea 的边框和背景:
frameVisible : false
backgroundVisible : false
并且设置为只读属性:readOnly: true。
切记,还要去掉TextArea的自带滚动条属性:verticalScrollBarPolicy: Qt.ScrollBarAlwaysOff,否则,滚动条就会出现在文字的右边。
还要对其implicitHeight进行设值,使得具有Label的效果。
但是如果仅仅利用TextArea就替代Label,那Qt就不需要有Label控件了,因此,并没有那么简单,如果仅仅设置了以上属性,当鼠标放到TextArea中时,可以看到是有轻微滚动的,这是因为虽然设置了verticalScrollBarPolicy:Qt.ScrollBarAlwaysOff属性,但是这仅仅是不显示滚动条,内容仍然是可以滚动的,考虑到TextArea是继承自ScrollView的(Inherits: ScrollView,详情查看帮助),因此可以设置contentItem属性以改变显示内容,由于显示的内容即为要进行鼠标操作(选择,复制等操作)的内容,因此,也用TextArea对其内容进行显示,并且支持鼠标操作,完成的父TextArea只起到一个控件占位的作用,以上,就实现了文字的显示以及选择与右键各操作了,其效果如下:
这里有一个细节,即对contentItem的TextArea设置了anchors.bottom和anchors.bottomMargin属性,如果不设置,其效果如下:
设置后,效果如下:
当然,我的截图中增加了其tooltip,以解决文字过长显示不全的问题,这里又有一个技巧,就是MouseArea的使用技巧,当进入是显示tooltip提示,退出区域时不显示tooltip提示,可是MouseArea会优先得到鼠标事件,这阻挡了TextArea捕捉鼠标,就会使得鼠标的选中文字不起作用,选中不了文字,鼠标事件只走到MouseArea就停止了,因此我们可以利用MouseArea的一个acceptedButtons属性,设置acceptedButtons: Qt.MiddleButton使得MouseArea只接收鼠标的中建而不接受左键和右键,这样,TextArea就可正常处理鼠标的选中文字与右键菜单的弹出了,至此,问题完美解决。
至于tooltip的实现,可以用QML的Window进行重写控件,实现其功能。