从2010年进入互联网+智能手机时代以来,各种各样的APP大行其道,手机上面的APP有很多流行的元素,开关按钮个人非常喜欢,手机QQ、360卫士、金山毒霸等,都有很多开关控制一些操作,在Qt widgets应用项目上,在项目中应用些类似的开关按钮,估计也会为项目增添不少新鲜感。
总结了大部分的开关按钮控件,基本上有两大类,第一类是纯代码绘制,这种对代码的掌控度要求比较高,但是灵活性比较好。第二类是贴图,专业的美工做好的各种状态的背景图片,只需要用代码将该图片画到界面上即可。为了能够涵盖两大类的开关按钮,特意将常见的四种类型(圆角矩形/内圆形/外圆形/图片)都集成到了自定义的开关按钮中。
运行效果:
1:纯代码绘制
纯代码绘制开关按钮,可以很灵活的设置各种颜色、间隔、文字等,还可以产生动画过度的滑动效果。
产生滑动效果采用定时器绘制的方式,自动计算滑块的X轴开始坐标,当滑块的X轴开始坐标到达滑块的X轴结束坐标时停止定时器。
void SwitchButton::updateValue() { if (checked) { if (startX < endX) { startX = startX + step; } else { startX = endX; timer->stop(); } } else { if (startX > endX) { startX = startX - step; } else { startX = endX; timer->stop(); } } update(); }
2:贴图绘制
void SwitchButton::drawImage(QPainter *painter) { painter->save(); QPixmap pix; if (!checked) { pix = QPixmap(imageOff); } else { pix = QPixmap(imageOn); } //自动等比例平滑缩放居中显示 int targetWidth = pix.width(); int targetHeight = pix.height(); pix = pix.scaled(targetWidth, targetHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation); int pixX = rect().center().x() - targetWidth / 2; int pixY = rect().center().y() - targetHeight / 2; QPoint point(pixX, pixY); painter->drawPixmap(point, pix); painter->restore(); }
有些人说PS一张精美的图片也不是很容易,需要专业的,这里推荐一个好方法,让你也可以获取到这些图片,其实大部分的APP都可以用解压软件打开,拓展名改为.zip即可,解压出来一般里面都含有绝大部分的图片,发现绝大部分的APP都喜欢用图片作为背景来展示一些效果,而不是原原本本的用代码一点点绘制。腾讯就是腾讯啊,大公司!人家的美工MM设计的图片那真的没得话说,绝对一流,手机QQ每次升级一个版本,我都会下过来将里面的精美图片图标之类的提取出来,以便项目使用。同时还推荐两个网站:http://www.easyicon.net/ 我的所有项目用到的ico图标都是这网站上面的。http://www.ui.cn/ 专业的设计师集中营,这里面成千上万的精美的设计的图片,可以多多参考。
完整代码:
switchbutton.h
#ifndef SWITCHBUTTON_H #define SWITCHBUTTON_H /** * 作者:feiyangqingyun(QQ:517216493) 2016-11-6 * 1:可设置开关按钮的样式 圆角矩形/内圆形/外圆形/图片 * 2:可设置选中和未选中时的背景颜色 * 3:可设置选中和未选中时的滑块颜色 * 4:可设置显示的文本 * 5:可设置滑块离背景的间隔 * 6:可设置圆角角度 */ #include <QWidget> class QTimer; class SwitchButton: public QWidget { Q_OBJECT public: enum ButtonStyle { ButtonStyle_Rect = 0, //圆角矩形 ButtonStyle_CircleIn = 1, //内圆形 ButtonStyle_CircleOut = 2,//外圆形 ButtonStyle_Image = 3 //图片 }; SwitchButton(QWidget *parent = 0); ~SwitchButton(); protected: void mousePressEvent(QMouseEvent *); void resizeEvent(QResizeEvent *); void paintEvent(QPaintEvent *); void drawBg(QPainter *painter); void drawSlider(QPainter *painter); void drawText(QPainter *painter); void drawImage(QPainter *painter); private: bool checked; //是否选中 ButtonStyle buttonStyle; //开关按钮样式 QColor bgColorOff; //关闭时背景颜色 QColor bgColorOn; //打开时背景颜色 QColor sliderColorOff; //关闭时滑块颜色 QColor sliderColorOn; //打开时滑块颜色 QColor textColorOff; //关闭时文本颜色 QColor textColorOn; //打开时文本颜色 QString textOff; //关闭时显示的文字 QString textOn; //打开时显示的文字 QString imageOff; //关闭时显示的图片 QString imageOn; //打开时显示的图片 int space; //滑块离背景间隔 int rectRadius; //圆角角度 int step; //每次移动的步长 int startX; //滑块开始X轴坐标 int endX; //滑块结束X轴坐标 QTimer *timer; //定时器绘制 private slots: void updateValue(); public: bool getChecked()const { return checked; } ButtonStyle getButtonStyle()const { return buttonStyle; } QColor getBgColorOff()const { return bgColorOff; } QColor getBgColorOn()const { return bgColorOn; } QColor getSliderColorOff()const { return sliderColorOff; } QColor getSliderColorOn()const { return sliderColorOn; } QColor getTextColorOff()const { return textColorOff; } QColor getTextColorOn()const { return textColorOn; } QString getTextOff()const { return textOff; } QString getTextOn()const { return textOn; } QString getImageOff()const { return imageOff; } QString getImageOn()const { return imageOn; } int getSpace()const { return space; } int getRectRadius()const { return rectRadius; } public slots: //设置是否选中 void setChecked(bool checked); //设置风格样式 void setButtonStyle(ButtonStyle buttonStyle); //设置背景颜色 void setBgColor(QColor bgColorOff, QColor bgColorOn); //设置滑块颜色 void setSliderColor(QColor sliderColorOff, QColor sliderColorOn); //设置文本颜色 void setTextColor(QColor textColorOff, QColor textColorOn); //设置文本 void setText(QString textOff, QString textOn); //设置背景图片 void setImage(QString imageOff, QString imageOn); //设置间隔 void setSpace(int space); //设置圆角角度 void setRectRadius(int rectRadius); signals: void checkedChanged(bool checked); }; #endif // SWITCHBUTTON_H