Let’s check the result first
buttonWithIcon
code explained:
base class: Button
final class : ButtonWithIcon
/**************** head file of Button *****************/
#ifndef BUTTON_H
#define BUTTON_H
#include <QWidget>
#include <QLabel>
class Button : public QWidget
{
Q_OBJECT
public:
explicit Button(QWidget *parent = nullptr);
void setText(const QString & str);
void setRoundRadius(int);
protected:
void paintEvent(QPaintEvent *event) ;
void enterEvent(QEvent *event) ;
void leaveEvent(QEvent *event) ;
void mousePressEvent(QMouseEvent * e);
void mouseReleaseEvent(QMouseEvent *event) ;
int imageWidth;//width of the icon on the left
int imageTextGap;
int leftGap;//gap between border and content
int rightGap;
int borderLeftGap;//to avoid blurry border ,we have to shrink 1pix or 2 depending on the width of border
signals:
void sigClicked();
private:
int textLen();
QString str;
int radius; //corner radius
bool hovering;
bool pressing;
};
#endif // BUTTON_H
/*********************** cpp file of Button **************************/
#include "button.h"
#include <QPainter>
#include "style.h"
#include <QDebug>
Button::Button(QWidget *parent) : QWidget(parent)
{
setMouseTracking(true);
setFixedSize(60,30);
str = "confirm";
radius = 15;
QFont font;
font.setPixelSize(15);
setFont(font);
pressing = false;
hovering = false;
leftGap = 6;
rightGap = 4;
borderLeftGap = 1;
imageWidth = 0;
imageTextGap = 0;
}
int Button::textLen(){
QFont f = font();
QFontMetrics m(f);
int w = m.horizontalAdvance(str);
return w;
}
void Button::setText(const QString & _str){
str = _str;
int gap = 2*borderLeftGap + leftGap + rightGap + imageWidth + imageTextGap;
if(textLen() > width() - gap){
setFixedWidth(textLen() + gap);
}
update();
}
void Button::setRoundRadius(int r){
radius = r;
update();
}
void Button::enterEvent(QEvent *event) {
hovering = true;
update();
}
void Button::leaveEvent(QEvent *event) {
hovering = false;
update();
}
void Button::mousePressEvent(QMouseEvent * e){
pressing = true;
update();
}
void Button::mouseReleaseEvent(QMouseEvent *event) {
pressing = false;
update();
emit sigClicked();
}
void Button::paintEvent(QPaintEvent *event) {
static const QString colorNorm = skinList[SkinIndex].normal;
static const QString colorHov = skinList[SkinIndex].hover;
static const QString colorPress = skinList[SkinIndex].pressed;
QPainter p(this);
p.setRenderHints(QPainter::Antialiasing);
int x = width();
int y = height();
QPen pen ;
pen.setWidth(borderLeftGap);
pen.setColor(QColor("black"));
p.setPen(pen);
QBrush brush = QBrush(QColor(colorNorm));
if(pressing){
brush = QBrush(QColor(colorPress));
}
else if(hovering){
brush = QBrush(QColor(colorHov));
}
p.setBrush(brush);
p.drawRoundedRect(QRectF(borderLeftGap,borderLeftGap,x-2*borderLeftGap,
y-2*borderLeftGap),radius,radius);
QFontMetrics m(font());
int h = m.height();
int len = textLen();
p.drawText(x-len-borderLeftGap - leftGap,(y + h)/2,str);
}
/********************* head file of ButtonWithIcon *************************************/
#ifndef BUTTONWITHICON_H
#define BUTTONWITHICON_H
#include <QWidget>
#include <QPainter>
#include <QDebug>
#include <QMouseEvent>
#include <QPixmap>
#include "button.h"
class ButtonWithIcon : public Button
{
Q_OBJECT
public:
explicit ButtonWithIcon(QWidget *parent = nullptr);
void setPixWidth(int w);
void setPixmap(const QPixmap & pix);
protected:
void paintEvent(QPaintEvent *event) ;
private:
QImage m_image;
int pixUpperGap;
};
#endif // BUTTONWITHICON_H
/**************************** cpp file of ButtonWithIcon **********************************/
#include "buttonwithicon.h"
ButtonWithIcon::ButtonWithIcon(QWidget *parent) : Button(parent)
{
imageWidth = 40;
imageTextGap = 8;
pixUpperGap = 10;
leftGap = 10;
this->setFixedHeight(imageWidth + pixUpperGap * 2);
}
void ButtonWithIcon::setPixWidth(int w){
imageWidth = w;
this->setFixedHeight(imageWidth + pixUpperGap * 2);
update();
}
void ButtonWithIcon::setPixmap(const QPixmap & pix){
m_image = pix.scaledToWidth(imageWidth).toImage();
update();
}
void ButtonWithIcon::paintEvent(QPaintEvent *event) {
Button::paintEvent(event);
QPainter p(this);
p.setRenderHints(QPainter::Antialiasing);
p.drawImage(QRectF(borderLeftGap+leftGap,pixUpperGap,imageWidth,imageWidth),
m_image);
}