通过绘制的方式实现自定义滑动开关,这个网上有很多了,今天自己在别人基础上进行了修改与优化,做了一个简单且好用的版本,在此记录一下,给需要的朋友参考。
源码下载地址:http://download.csdn.net/detail/dxzysk/9810692
绘制背景
void CSwitchWidget::DrawPressBkGround(QPainter *painter, QRect &rect, uchar state)
{
QBrush oldbrush = painter->brush();
QPen oldpen = painter->pen();
painter->save();
int panestyle = GetPressStyle();
int x1 = rect.left(); int y1 = rect.top();
int x2 = rect.right(); int y2 = rect.bottom();
int width = rect.width(); int height = rect.height();
if (panestyle == GRAPH_PRESSSTYLE_SYSTEM1) {
if (state > 0) {
painter->setPen(Qt::NoPen);
QLinearGradient linGrad(rect.left(), rect.top(), rect.left(), rect.bottom());
linGrad.setColorAt(0, m_onbkcolor1);
linGrad.setColorAt(1, m_onbkcolor2);
linGrad.setSpread(QGradient::PadSpread);
painter->setBrush(linGrad);
painter->drawRoundedRect(rect, 5.0, 5.0);
}
else {
painter->setPen(Qt::NoPen);
QLinearGradient linGrad(rect.left(), rect.top(), rect.left(), rect.bottom());
linGrad.setColorAt(0, m_offbkcolor1);
linGrad.setColorAt(1, m_offbkcolor2);
linGrad.setSpread(QGradient::PadSpread);
painter->setBrush(linGrad);
painter->drawRoundedRect(rect, 5.0, 5.0);
}
painter->setBrush(Qt::NoBrush);
QPen tmppen(Qt::darkGray);
tmppen.setWidth(2.0);
painter->setPen(tmppen);
painter->drawRoundedRect(rect, 5.0, 5.0);
}
else if (panestyle == GRAPH_PRESSSTYLE_SYSTEM2) {
//path
QPainterPath path;
path.moveTo(x1 + height / 2.0, y1);
path.arcTo(QRectF(x1, y1, height, height), 90, 180);
path.lineTo(x2 - height / 2.0, y2);
path.arcTo(QRectF(x2 - height, y1, height, height), 270, 180);
path.lineTo(x1 + height / 2.0, y1);
QPainterPath pathrect;
pathrect.moveTo(rect.left(), rect.top());
pathrect.lineTo(rect.left(), rect.bottom());
pathrect.lineTo(rect.right(), rect.bottom());
pathrect.lineTo(rect.right(), rect.top());
pathrect.lineTo(rect.left(), rect.top());
QPainterPath interpath = path.intersected(pathrect);
if (state > 0) {
painter->setPen(Qt::NoPen);
QLinearGradient linGrad(rect.left(), rect.top(), rect.left(), rect.bottom());
linGrad.setColorAt(0, m_onbkcolor1);
linGrad.setColorAt(1, m_onbkcolor2);
linGrad.setSpread(QGradient::PadSpread);
painter->setBrush(linGrad);
painter->drawPath(interpath);
}
else {
painter->setPen(Qt::NoPen);
QLinearGradient linGrad(rect.left(), rect.top(), rect.left(), rect.bottom());
linGrad.setColorAt(0, m_offbkcolor1);
linGrad.setColorAt(1, m_offbkcolor2);
linGrad.setSpread(QGradient::PadSpread);
painter->setBrush(linGrad);
painter->drawPath(interpath);
}
painter->setBrush(Qt::NoBrush);
painter->setPen(QColor(0, 0, 0, 255));
painter->drawPath(interpath);
}
painter->restore();
painter->setPen(oldpen);
painter->setBrush(oldbrush);
}
绘制文字
void CSwitchWidget::DrawPressText(QPainter *painter, QRect &rect, uchar state)
{
QBrush oldbrush = painter->brush();
QPen oldpen = painter->pen();
painter->save();
int x1 = rect.left(); int y1 = rect.top();
int x2 = rect.right(); int y2 = rect.bottom();
int width = rect.width(); int height = rect.height();
QPen tmppen(m_textcolor);
if (state > 0) {
painter->setFont(m_textfont);
painter->setPen(tmppen);
painter->drawText((int)(x1 + width / 2.0), y1, (int)(width / 2.0), height, Qt::AlignCenter, m_onname);
}
else {
painter->setFont(m_textfont);
painter->setPen(tmppen);
painter->drawText(x1, y1, (int)(width / 2.0), height, Qt::AlignCenter, m_offname);
}
painter->restore();
painter->setPen(oldpen);
painter->setBrush(oldbrush);
}
绘制滑动条
void CSwitchWidget::DrawPressSlide(QPainter *painter, QRect &rect, uchar state)
{
QBrush oldbrush = painter->brush();
QPen oldpen = painter->pen();
painter->save();
int panestyle = GetPressStyle();
int x1 = rect.left(); int y1 = rect.top();
int x2 = rect.right(); int y2 = rect.bottom();
int width = rect.width(); int height = rect.height();
QRect sliderect;
if (panestyle == GRAPH_PRESSSTYLE_SYSTEM1) {
if (state > 0) {
sliderect.setLeft(rect.left() + 2);
sliderect.setTop(rect.top() + 2);
sliderect.setWidth((int)(rect.width() / 2.0 - 4));
sliderect.setHeight(rect.height() - 4);
painter->setPen(Qt::NoPen);
QLinearGradient linGrad(rect.left(), rect.top(), rect.left(), rect.bottom());
linGrad.setColorAt(0, m_slidecolor1);
linGrad.setColorAt(1, m_slidecolor2);
linGrad.setSpread(QGradient::PadSpread);
painter->setBrush(linGrad);
painter->drawRoundedRect(sliderect, 5.0, 5.0);
}
else {
sliderect.setLeft(rect.right() - (int)(rect.width() / 2.0) + 2);
sliderect.setTop(rect.top() + 2);
sliderect.setWidth((int)(rect.width() / 2.0 - 4));
sliderect.setHeight(rect.height() - 4);
painter->setPen(Qt::NoPen);
QLinearGradient linGrad(rect.left(), rect.top(), rect.left(), rect.bottom());
linGrad.setColorAt(0, m_slidecolor1);
linGrad.setColorAt(1, m_slidecolor2);
linGrad.setSpread(QGradient::PadSpread);
painter->setBrush(linGrad);
painter->drawRoundedRect(sliderect, 5.0, 5.0);
}
painter->setBrush(Qt::NoBrush);
painter->setPen(QColor(0, 0, 0, 255));
painter->drawRoundedRect(sliderect, 5.0, 5.0);
painter->setPen(QColor(54, 54, 54));
painter->drawLine(sliderect.left() + sliderect.width() / 2.0, sliderect.top() + sliderect.height() / 4.0 + 2, sliderect.left() + sliderect.width() / 2.0, sliderect.bottom() - sliderect.height() / 4.0 - 2);
painter->drawLine(sliderect.left() + sliderect.width() / 2.0 - 5, sliderect.top() + sliderect.height() / 4.0 + 2, sliderect.left() + sliderect.width() / 2.0 - 5, sliderect.bottom() - sliderect.height() / 4.0 - 2);
painter->drawLine(sliderect.left() + sliderect.width() / 2.0 + 5, sliderect.top() + sliderect.height() / 4.0 + 2, sliderect.left() + sliderect.width() / 2.0 + 5, sliderect.bottom() - sliderect.height() / 4.0 - 2);
painter->setPen(QColor(134, 134, 134));
painter->drawLine(sliderect.left() + sliderect.width() / 2.0 + 1, sliderect.top() + sliderect.height() / 4.0 + 2, sliderect.left() + sliderect.width() / 2.0 + 1, sliderect.bottom() - sliderect.height() / 4.0 - 2);
painter->drawLine(sliderect.left() + sliderect.width() / 2.0 - 5 + 1, sliderect.top() + sliderect.height() / 4.0 + 2, sliderect.left() + sliderect.width() / 2.0 - 5 + 1, sliderect.bottom() - sliderect.height() / 4.0 - 2);
painter->drawLine(sliderect.left() + sliderect.width() / 2.0 + 5 + 1, sliderect.top() + sliderect.height() / 4.0 + 2, sliderect.left() + sliderect.width() / 2.0 + 5 + 1, sliderect.bottom() - sliderect.height() / 4.0 - 2);
}
}
测试
SwitchTestDialog::SwitchTestDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SwitchTestDialog)
{
//ui->setupUi(this);
this->setWindowTitle("SwitchTest");
resize(400, 300);
// QPushButton* btn = new QPushButton(this);
// btn->setGeometry(QRect(50, 150, 301, 50));
QLabel *label1 = new QLabel("swich button1:", this);
//label1->setObjectName(QStringLiteral("label"));
label1->setGeometry(QRect(10, 30, 200, 50));
CSwitchWidget* wigt = new CSwitchWidget(this);
//wigt->SetPressStyle(GRAPH_PRESSSTYLE_SYSTEM2);
wigt->setGeometry(QRect(150, 30, 200, 50));
wigt->SetSwitchState(1);
QLabel *label2 = new QLabel("swich button2:", this);
//label1->setObjectName(QStringLiteral("label"));
label2->setGeometry(QRect(10, 130, 200, 50));
CSwitchWidget* wigt2 = new CSwitchWidget(this);
wigt2->SetPressStyle(GRAPH_PRESSSTYLE_SYSTEM2);
wigt2->setGeometry(QRect(150, 130, 150, 50));
wigt2->SetSwitchState(1);
}