QT 实现Android 风格的开关控件
技术:QT + 控件
概述
本例子是举例如何使用QT实现Android风格的开关控件
详细
本例子是举例如何使用QT实现Android风格的开关控件,可以使用画颜色的方式,也可使用画图片方式。
一、运行效果
这是画颜色的方式,画图片的方式的运行效果这里不再展示
二、实现过程
要实现开关控件,我们需要按以下步骤进行实现
1. 数据定义
QColor m_onColor; //开状态的颜色 QColor m_offColor; //关状态的颜色 bool m_Value; //开关值 int m_timerID; //移动定时器id int m_offset; //移动过程中圆心的x坐标 bool m_isMove; QPoint m_pressPos; //鼠标按下的位置 bool m_DisableVal; QPixmap m_BkgPixmapNormal; //使用图片方式时保存开状态背景 QPixmap m_BkgPixmapPress; //使用图片方式时保存关状态背景 QPixmap m_ChunkPixmapNormal; //使用图片方式时保存开状态滑块 QPixmap m_ChunkPixmapPress;//使用图片方式时保存关状态滑块
2. 鼠标事件处理,这里只写出鼠标释放部分的代码
if (m_isMove) { m_isMove = false; m_offset = 0; int xMove = event->pos().x()-m_pressPos.x(); if (abs(xMove) >= (this->rect().width()-this->rect().height())/2) { if (m_reverse) { if (xMove > 0 && m_Value) { setOnoffStatus(!m_Value); emit valueChanged( m_Value); } else if (!m_Value) { setOnoffStatus(!m_Value); emit valueChanged( m_Value); } else { update(); } } else { if (xMove < 0 && m_Value) { setOnoffStatus(!m_Value); emit valueChanged( m_Value); } else if (!m_Value) { setOnoffStatus(!m_Value); emit valueChanged( m_Value); } else { update(); } } } else { update(); } } else { changeStatus(!m_Value); }
3. 动画过渡过程处理
if (m_reverse) { if (m_Value) { m_offset -= 8; } else { m_offset += 8; } } else { if (m_Value) { m_offset += 8; } else { m_offset -= 8; } } if ((m_offset <= this->rect().height()/2) || (m_offset >= (this->rect().width()-this->rect().height()/2))) { killTimer(m_timerID); m_timerID = 0; m_offset = 0; } update();
4. 根据各数据的值画出画面效果, 这里只展示部分代码
//画关闭色 QPainterPath path; QRectF mrect = QRect(rc.x()+1, rc.top()+margin+1, m_offset-1, margin*4); path.moveTo(mrect.topRight() - QPointF(radius, 0)); path.lineTo(mrect.topLeft() + QPointF(radius, 0)); path.quadTo(mrect.topLeft(), mrect.topLeft() + QPointF(0, radius)); path.lineTo(mrect.bottomLeft() + QPointF(0, -radius)); path.quadTo(mrect.bottomLeft(), mrect.bottomLeft() + QPointF(radius, 0)); path.lineTo(mrect.bottomRight() - QPointF(radius, 0)); path.quadTo(mrect.bottomRight(), mrect.bottomRight() + QPointF(0, -radius)); path.lineTo(mrect.topRight() + QPointF(0, radius)); path.quadTo(mrect.topRight(), mrect.topRight() + QPointF(-radius, -0)); painter.setPen(QPen(QColor(70, 70, 70))); painter.setBrush(QBrush(QColor(m_onColor.red()*2/3, m_onColor.green()*2/3, m_onColor.blue()*2/3))); painter.fillPath(path, m_onColor); painter.drawPath(path); //画打开色 QPainterPath path2; mrect = QRect(m_offset, rc.top()+margin+1, rc.width()-m_offset-1, margin*4); path2.moveTo(mrect.topRight() - QPointF(radius, 0)); path2.lineTo(mrect.topLeft() + QPointF(radius, 0)); path2.quadTo(mrect.topLeft(), mrect.topLeft() + QPointF(0, radius)); path2.lineTo(mrect.bottomLeft() + QPointF(0, -radius)); path2.quadTo(mrect.bottomLeft(), mrect.bottomLeft() + QPointF(radius, 0)); path2.lineTo(mrect.bottomRight() - QPointF(radius, 0)); path2.quadTo(mrect.bottomRight(), mrect.bottomRight() + QPointF(0, -radius)); path2.lineTo(mrect.topRight() + QPointF(0, radius)); path2.quadTo(mrect.topRight(), mrect.topRight() + QPointF(-radius, -0)); painter.setPen(QPen(QColor(70, 70, 70))); painter.setBrush(QBrush(QColor(m_offColor.red()*2/3, m_offColor.green()*2/3, m_offColor.blue()*2/3))); painter.fillPath(path2, m_offColor); painter.drawPath(path2); //画圆圈 if (m_offset > rc.width()/2) { painter.setPen(QPen(QColor(70, 70, 70))); painter.setBrush(QBrush(m_onColor)); painter.drawEllipse(rc.x()+m_offset-rc.height()/2, rc.top(), rc.height(), rc.height()); } else { painter.setPen(QPen(QColor(70, 70, 70))); painter.setBrush(QBrush(m_offColor)); painter.drawEllipse(rc.x()+m_offset-rc.height()/2, rc.top(), rc.height(), rc.height()); }
三、项目结构图
四、控件使用介绍
控件创建后可以使用以下两个函数改变控件开关状态的颜色
/*set text on color*/ const QColor onColor() const; void setOnColor(const QColor &data); /*set text off color*/ const QColor offColor() const; void setOffColor(const QColor &data);
如果要使用画图片的方式,可使用以下函数设置图片
void setNormalBkgPix(const QPixmap &pix);//开状态背景 void setPressBkgPix(const QPixmap &pix); //关状态背景 void setNormalChunkPix(const QPixmap &pix); //开状态滑块 void setPressChunkPix(const QPixmap &pix); //关状态滑块
本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
手机上随时阅读、收藏该文章 ?请扫下方二维码