这次放出一个,自己写得的qml的spinBox,主要是用来代替系统自带的控件,个人感觉,1.0和2.0版本的spinBox不管是样式,还是功能,都不能满足我的需求,网上自定义的spinBox好像也不是很多,所以,最后不得不像写c语言一样,自定义了一个新的spinBox一点一点实现其功能。
目前来说,一方面是样式上,采用了两个用图标库图案的按钮,加上一个现实数字的label,关于图标库的使用,这里也会顺便提一下,总得来说,图标库里的内容还是很丰富的,关键是没有背景色,可以直接拿来用,基本可以满足图标上的开发需求。这样组合的自定义spinBox在样式上自由度非常大。而另一方面,主要是实现了一下长按效果,长按使数字自增或者自减,这个效果应用的地方还是很多的,基本需要用到spinBox的多少都会需要。
首先,先把图标库的使用部分贴上来,图标库的使用,其实网上也有很多了,我这边贴个代码,在上个网盘的链接,下下来自己弄一下,很快的。
在main.cpp中加入以下代码:
QFontDatabase::addApplicationFont(":/res/font/fontawesome-webfont.ttf");
在资源文件中添加下载好的图标库文件,怎么添加不用我说的吧,基础操作,自行百度。
这边是给的网盘链接,里面有我现在用的数据库文件:
链接:https://pan.baidu.com/s/1dNZEvN8kjGPEwegP8sdhIw
提取码:b58t
配置好之后,就可以直接在qml中使用了,贴一个用法例子,后面的spinBox里也有,如果有人只是单纯地找图标库的,后面spinBox的内容可以不看了:
Button{
id: text1
width: 50
height: 30
Text {
anchors.centerIn: parent
text: qsTr("\uf068") //这里的text填你想放上去的图标码,\u 是前缀,后四位 f068是具体编码,图标码可在官网查询
font.family: "fontawesome" //原本选择字体的部分,指向图标库文件的名字
color: t_color //这里是图标颜色,我设置了黑白两个主题,所以用得是自定义的全局变量
font.pixelSize: 20
}
}
本身结构还是比较简单的两个按钮拼上一个label,尺寸定位之类的看自己喜欢,所以我这边就直接上代码,用得话自己新建个qml,封装进去,改一下id,objectname之类的,应该就可以调用了:
import QtQuick 2.2 //头文件部分在这里,这是我用的版本,出现版本问题参照这个来
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.2
Row{
anchors.top: parent.top
anchors.left: joint1.right
spacing: 0
Button{
id: joint1down
objectName: "joint1down"
width: 50
height: 30
background: Rectangle{ //我自定义的渐变,要用的改改颜色,不用的删掉就是了
border.color: "gray"
border.width: 1
radius: 7
gradient: Gradient {
GradientStop {
position: 0.00;
color: t_background_color
}
GradientStop {
position: 0.70;
color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
}
GradientStop {
position: 1.00;
color: t_button_color
}
}
}
Text { //按钮图标,好像是 减号 “-”
anchors.centerIn: parent
text: qsTr("\uf068")
font.family: "fontawesome"
color: t_color
font.pixelSize: 20
}
MouseArea{ //实现按压和长按效果
anchors.fill: parent
width: robot.width
height: robot.height
onPressed: {
tarjoint = "joint1"
jointDelPressTimer.start();
}
onReleased: {
jointDelPressTimer.stop();
}
}
}
Label{ //单纯地显示数组的label,样式自定,可以搞一手特殊字体,我懒得弄了
id: joint1param
objectName: "join1param"
width: 200
height: 25
anchors.verticalCenter: parent.verticalCenter
background: Rectangle{
color: t_background_color
border.color: t_color
border.width: 1
}
Text {
id: param1
text: joint_1.toString()
font.pixelSize: 20
color: t_color
anchors.centerIn: parent
}
}
Button{ //加号“+”按钮
id: joint1add
objectName: "joint2down"
width: 50
height: 30
background: Rectangle{
border.color: "gray"
border.width: 1
radius: 7
gradient: Gradient {
GradientStop {
position: 0.00;
color: t_background_color
}
GradientStop {
position: 0.70;
color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
}
GradientStop {
position: 1.00;
color: t_button_color
}
}
}
Text {
anchors.centerIn: parent
text: qsTr("\uf067")
font.family: "fontawesome"
color: t_color
font.pixelSize: 20
}
MouseArea{
anchors.fill: parent
width: robot.width
height: robot.height
onPressed: {
tarjoint = "joint1"
jointAddPressTimer.start();
}
onReleased: {
jointAddPressTimer.stop();
}
}
}
}
当然,如果只拷上边的代码,是没有长按效果,这玩意的实现主要是两点:
1、怎么得到长按的信号,并实现其效果
2、怎么得到长按取消的信号,并结束其效果
第一个问题,到是非常简单,qml里也保留了Qt中button的信号,最基础的三个,按压(pressed),松开(released)以及点击(clicked),这三个信号,用的最多的是clicked,一般按钮里都是onClicked,而在这里,当然不可能是选择clicked这个自带结束能力的信号了,所以,效果的实现,就是通过接收pressed按压信号来启动就可以了。一般来说是将效果封装进一个函数,直接调用就好。而我这里,则是启动了一个定义在qml里的计时器,因为实现的效果是长按,label中数字自增,增减,所以,只需要通过计时器的变化,同步到label中text的数值变化就可以了,下面是两个计时器的定义:
Timer {
id: jointDelPressTimer
interval: 100; //计时器间隔
running: false;
repeat: true //是否可以重复触发,还是触发一次就停止
triggeredOnStart: true //开始计时立刻触发效果
onTriggered: {
if (tarjoint === "joint1")
{
joint_1 = (joint_1 - joint_bj / 10).toFixed(6)
}
else if(tarjoint === "joint2")
{
joint_2 = (joint_2 - joint_bj / 10).toFixed(6)
}
else if (tarjoint === "joint3")
{
joint_3 = (joint_3 - joint_bj / 10).toFixed(6)
}
else if(tarjoint === "joint4")
{
joint_4 = (joint_4 - joint_bj / 10).toFixed(6)
}
else if(tarjoint === "joint5")
{
joint_5 = (joint_5 - joint_bj / 10).toFixed(6)
}
else if(tarjoint === "joint6")
{
joint_6 = (joint_6 - joint_bj / 10).toFixed(6)
}
else
{
warmming1.visible = true
}
}
}
Timer {
id: jointAddPressTimer
interval: 100; //计时器间隔
running: false;
repeat: true //是否可以重复触发,还是触发一次就停止
triggeredOnStart: true //开始计时立刻触发效果
onTriggered: {
if (tarjoint === "joint1")
{
joint_1 = (joint_1 + joint_bj / 10).toFixed(6)
}
else if(tarjoint === "joint2")
{
joint_2 = (joint_2 + joint_bj / 10).toFixed(6)
}
else if (tarjoint === "joint3")
{
joint_3 = (joint_3 + joint_bj / 10).toFixed(6)
}
else if(tarjoint === "joint4")
{
joint_4 = (joint_4 + joint_bj / 10).toFixed(6)
}
else if(tarjoint === "joint5")
{
joint_5 = (joint_5 + joint_bj / 10).toFixed(6)
}
else if(tarjoint === "joint6")
{
joint_6 = (joint_6 + joint_bj / 10).toFixed(6)
}
else
{
warmming1.visible = true
}
}
}
上面的两个计时器,一增一减,其中大部分的属性也都给了介绍,我是有六个地方需要用,你们根据自己的需求,自己看着改吧,应该可以看懂,不多说了。
而第二个结束信号的问题,当然很简单,直接用released信号就可以了,但是,也没有直接用那么简单,因为直接如果直接用pressed和released信号,你们会得到一个额外的神奇效果,按下==》数字自增==》鼠标(手指)移到按钮范围外松开==》数字持续自增,是的,如果你们直接使用这两个信号,一旦移动到按钮范围之外,你的released信号就会失效,这在工业上是非常危险的,所以,我把这两个信号都往下放了一层,先加一个mouseArea在按钮里,再实现这两个信号的效果,实测可用,可用在屏幕任意地方松开你的鼠标或者手指,按钮都可以接收到released信号而结束,当然,如果你们想要那种松开手指的自增,也是可以直接用的,算是一个额外效果吧。