Qt的控件中提供了按钮类,我们在调用一个按钮控件的时候,一般通过使用按钮类本身的接口函数已经够用了。
在添加按钮的图标或者背景的时候可以通过调用如下所示的接口函数。
void setIcon(const QIcon &icon)
虽然Qt已经提供了非常完美的接口函数,但是总有一些情况是它无法满足的:比如在使用一些图片进行缩放的时候,会因为图片放大后失真,导致贴上去的图不精确,如果这个图片是符合九宫格缩放后不改变原形态的这种情况,我们可以进行重新定制一个专属按钮。
关键代码:
/*
** 功能 : 九宫格图处理
** picName : 图片名字
** iHorzSplit : 四个角上格子的宽度
** iVertSplit : 四个角上格子的高度
** DstWidth : 整个图片缩放的宽度
** DstWidth : 整个图片缩放的高度
** 返回值 : 处理完成的图片
*/
QPixmap* Test1Button::ninePatch(QString picName,double iHorzSplit, double iVertSplit, double DstWidth, double DstHeight)
{
QPixmap* pix = new QPixmap(picName);
int pixWidth = pix->width();
int pixHeight = pix->height();
QPixmap pix_1 = pix->copy(0, 0, iHorzSplit, iVertSplit);//0 0 22 14
QPixmap pix_2 = pix->copy(iHorzSplit, 0, pixWidth-iHorzSplit*2, iVertSplit);//22 0 22 14
QPixmap pix_3 = pix->copy(pixWidth-iHorzSplit, 0, iHorzSplit, iVertSplit);// 44 0 22 14
QPixmap pix_4 = pix->copy(0, iVertSplit, iHorzSplit, pixHeight-iVertSplit*2);//0 14 22 16
QPixmap pix_5 = pix->copy(iHorzSplit, iVertSplit, pixWidth-iHorzSplit*2, pixHeight-iVertSplit*2);//22 14 22 16
QPixmap pix_6 = pix->copy(pixWidth-iHorzSplit, iVertSplit, iHorzSplit, pixHeight-iVertSplit*2);//44 14 22 16
QPixmap pix_7 = pix->copy(0, pixHeight-iVertSplit, iHorzSplit, iVertSplit);//0 30 22 14
QPixmap pix_8 = pix->copy(iHorzSplit, pixHeight-iVertSplit, pixWidth-iHorzSplit*2, iVertSplit);//22 30 22 14
QPixmap pix_9 = pix->copy(pixWidth-iHorzSplit, pixHeight-iVertSplit, iHorzSplit, iVertSplit);//44 30 22 14
pix_2 = pix_2.scaled(DstWidth-iHorzSplit*2+6,iVertSplit, Qt::IgnoreAspectRatio);//保持高度拉宽
pix_4 = pix_4.scaled(iHorzSplit, DstHeight-iVertSplit*2+4, Qt::IgnoreAspectRatio);//保持宽度拉高
pix_5 = pix_5.scaled(DstWidth-iHorzSplit*2+6,DstHeight-iVertSplit*2+4, Qt::IgnoreAspectRatio);//宽高都缩放
pix_6 = pix_6.scaled(iHorzSplit, DstHeight-iVertSplit*2+4, Qt::IgnoreAspectRatio);//保持宽度拉高
pix_8 = pix_8.scaled(DstWidth-iHorzSplit*2+6, iVertSplit);//保持高度拉宽
QPixmap* resultImg =new QPixmap(DstWidth, DstHeight);
QPainter* painter = new QPainter(resultImg);
if (!resultImg->isNull()) {
painter->drawPixmap(-3,0,pix_1);
painter->drawPixmap(iHorzSplit-3, 0, pix_2);
painter->drawPixmap(DstWidth-iHorzSplit+3,0,pix_3);
painter->drawPixmap(-3, iVertSplit, pix_4);
painter->drawPixmap(iHorzSplit-3, iVertSplit, pix_5);
painter->drawPixmap(DstWidth-iHorzSplit+3, iVertSplit, pix_6);
painter->drawPixmap(-3, DstHeight-iVertSplit+4, pix_7);
painter->drawPixmap(iHorzSplit-3, DstHeight-iVertSplit+4, pix_8);
painter->drawPixmap(DstWidth-iHorzSplit+3, DstHeight-iVertSplit+4, pix_9);
painter->end();
}
return resultImg;
}
关于图片的缩放处理,我借鉴了csdn大佬的九宫格缩放图片算法:https://blog.csdn.net/caoshangpa/article/details/53391230
但是在大佬的源码程序中,我遇到了 按钮重绘图片后存在黑边的问题。在我自己的代码中已经将它解决了。
完整代码:
imagebutton.h
#ifndef TEST1BUTTON_H
#define TEST1BUTTON_H
#include
#include
class Test1Button : public QPushButton
{
Q_OBJECT
public:
explicit Test1Button(QWidget *parent = nullptr);
explicit Test1Button(const QString&text,QWidget *parent = nullptr);
~Test1Button();
void setText(const QString&text);
void setMyIcon(const QString &icon);
void setImageName(const QString &img);
protected:
void paintEvent(QPaintEvent *event);
void drawText(QPainter *painter);
void drawImage(QPainter*painter);
void drawIcon(QPainter*painter);
QPixmap* ninePatch(QString picName,double iHorzSplit,double iVertSplit, double DstWidth, double DstHeight);
QPixmap generatePixmap(const QPixmap& img_in, int radius1,int radius2);
private:
QString mFileName;
QString mText;
QString mIcon;
int mWidth;
int mHeight;
bool pressed;
};
#endif // TEST1BUTTON_H
imagebutton.cpp
#include "imagebutton.h"
#include
#include
#include
#include
#include
Test1Button::Test1Button(QWidget *parent):QPushButton(parent),mWidth(100),mHeight(100)
{
pressed = false;
mText = "";
mIcon = "";
mFileName = "/home/rabbitchenc/Image/btn2_normal.png";
setSizePolicy(QSizePolicy::Ignored,
QSizePolicy::Ignored
);
connect(this,&QPushButton::pressed,[=](){
pressed = true;
setImageName("/home/rabbitchenc/Image/btn2_pressed.png");
});
connect(this,&QPushButton::released,[=](){
pressed = false;
setImageName("/home/rabbitchenc/Image/btn2_normal.png");
});
}
Test1Button::Test1Button(const QString&text,QWidget *parent):QPushButton(parent),mWidth(100),mHeight(30),mText(text)
{
pressed = false;
mText = "";
mIcon = "";
setImageName("/home/rabbitchenc/Image/btn2_normal.png");
setSizePolicy(QSizePolicy::Preferred,
QSizePolicy::Preferred
);
connect(this,&QPushButton::pressed,[=](){
setImageName("/home/rabbitchenc/Image/btn2_pressed.png");
});
connect(this,&QPushButton::released,[=](){
setImageName("/home/rabbitchenc/Image/btn2_normal.png");
});
}
Test1Button::~Test1Button()
{
}
void Test1Button::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::TextAntialiasing);
drawImage(&painter);
drawText(&painter);
drawIcon(&painter);
}
//组按键的状态被解决
void Test1Button::drawImage(QPainter*painter)
{
painter->save();
QPixmap pixmap;
mWidth = width();
mHeight = height();
if(isEnabled()){
if(isCheckable()){
if(isChecked()){
mFileName = "/home/rabbitchenc/Image/btn2_pressed.png";
}else{
mFileName = "/home/rabbitchenc/Image/btn2_normal.png";
}
if(pressed){
mFileName = "/home/rabbitchenc/Image/btn2_focused.png";
}
}
}else {
mFileName ="/home/rabbitchenc/Image/btn2_disable.png";
}
qDebug() << "filename" <<mFileName;
pixmap = QPixmap( mFileName);
int pixWidth = pixmap.width();
int pixHeight = pixmap.height();
pixmap = *ninePatch( mFileName,pixWidth/3,pixHeight/3, mWidth,mHeight);
pixmap = generatePixmap(pixmap, 9,9);
painter->drawPixmap(0,0,mWidth,mHeight,pixmap);
painter->restore();
}
/*
** 功能 : 九宫格图处理
** picName : 图片名字
** iHorzSplit : 四个角上格子的宽度
** iVertSplit : 四个角上格子的高度
** DstWidth : 整个图片缩放的宽度
** DstWidth : 整个图片缩放的高度
** 返回值 : 处理完成的图片
*/
//猜测出现这种问题的原因1 精度不够 问题二 图片边框 本身就是存在问题的 换一张图进行尝试
QPixmap* Test1Button::ninePatch(QString picName,double iHorzSplit, double iVertSplit, double DstWidth, double DstHeight)//将数据都修改成 double类型 进行测试
{
QPixmap* pix = new QPixmap(picName);
int pixWidth = pix->width();
int pixHeight = pix->height();
QPixmap pix_1 = pix->copy(0, 0, iHorzSplit, iVertSplit);//0 0 22 14
QPixmap pix_2 = pix->copy(iHorzSplit, 0, pixWidth-iHorzSplit*2, iVertSplit);//22 0 22 14
QPixmap pix_3 = pix->copy(pixWidth-iHorzSplit, 0, iHorzSplit, iVertSplit);// 44 0 22 14
QPixmap pix_4 = pix->copy(0, iVertSplit, iHorzSplit, pixHeight-iVertSplit*2);//0 14 22 16
QPixmap pix_5 = pix->copy(iHorzSplit, iVertSplit, pixWidth-iHorzSplit*2, pixHeight-iVertSplit*2);//22 14 22 16
QPixmap pix_6 = pix->copy(pixWidth-iHorzSplit, iVertSplit, iHorzSplit, pixHeight-iVertSplit*2);//44 14 22 16
QPixmap pix_7 = pix->copy(0, pixHeight-iVertSplit, iHorzSplit, iVertSplit);//0 30 22 14
QPixmap pix_8 = pix->copy(iHorzSplit, pixHeight-iVertSplit, pixWidth-iHorzSplit*2, iVertSplit);//22 30 22 14
QPixmap pix_9 = pix->copy(pixWidth-iHorzSplit, pixHeight-iVertSplit, iHorzSplit, iVertSplit);//44 30 22 14
pix_2 = pix_2.scaled(DstWidth-iHorzSplit*2+6,iVertSplit, Qt::IgnoreAspectRatio);//保持高度拉宽
pix_4 = pix_4.scaled(iHorzSplit, DstHeight-iVertSplit*2+4, Qt::IgnoreAspectRatio);//保持宽度拉高
pix_5 = pix_5.scaled(DstWidth-iHorzSplit*2+6,DstHeight-iVertSplit*2+4, Qt::IgnoreAspectRatio);//宽高都缩放
pix_6 = pix_6.scaled(iHorzSplit, DstHeight-iVertSplit*2+4, Qt::IgnoreAspectRatio);//保持宽度拉高
pix_8 = pix_8.scaled(DstWidth-iHorzSplit*2+6, iVertSplit);//保持高度拉宽
QPixmap* resultImg =new QPixmap(DstWidth, DstHeight);
QPainter* painter = new QPainter(resultImg);
if (!resultImg->isNull()) {
painter->drawPixmap(-3,0,pix_1);
painter->drawPixmap(iHorzSplit-3, 0, pix_2);
painter->drawPixmap(DstWidth-iHorzSplit+3,0,pix_3);
painter->drawPixmap(-3, iVertSplit, pix_4);
painter->drawPixmap(iHorzSplit-3, iVertSplit, pix_5);
painter->drawPixmap(DstWidth-iHorzSplit+3, iVertSplit, pix_6);
painter->drawPixmap(-3, DstHeight-iVertSplit+4, pix_7);
painter->drawPixmap(iHorzSplit-3, DstHeight-iVertSplit+4, pix_8);
painter->drawPixmap(DstWidth-iHorzSplit+3, DstHeight-iVertSplit+4, pix_9);
painter->end();
}
return resultImg;
}
/**
* 圆角图片
* src 原图片
* radius 图片半径
*/
QPixmap Test1Button::generatePixmap(const QPixmap& img_in, int radius1,int radius2) {
if (img_in.isNull())
{
return QPixmap();
}
QSize size(img_in.size());
QBitmap mask(size);
QPainter painter(&mask);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.fillRect(mask.rect(), Qt::white);
painter.setBrush(QColor(0, 0, 0));
painter.drawRoundedRect(mask.rect(), radius1, radius2);
QPixmap image = img_in;
image.setMask(mask);
return image;
}
//添加文字
void Test1Button::drawText(QPainter *painter)
{
painter->save();
QFont font = painter->font();
painter->drawText(0,0,mWidth,mHeight,Qt::AlignCenter,mText);
painter->restore();
}
//添加图标
void Test1Button::drawIcon(QPainter*painter)
{
painter->save();
qDebug() << "icon" << mIcon;
QPixmap pixmap(mIcon);
if(pressed){
painter->drawPixmap((width()-pixmap.width())/2,(height()-pixmap.height())/2,pixmap.width(),pixmap.height(),pixmap);
}else{
painter->drawPixmap((width()-pixmap.width())/2,(height()-pixmap.height())/2,pixmap.width(),pixmap.height(),pixmap);
}
painter->restore();
}
void Test1Button::setText(const QString&text)
{
mText = text;
update();
}
void Test1Button::setMyIcon(const QString &icon)
{
mIcon = icon;
update();
}
void Test1Button::setImageName(const QString &img)
{
mFileName = img;
update();
}
我是刚刚学习刚刚学习Qt和cpp两个月的菜鸡程序员,会水群,白嫖,写bug,请大佬门多多指教。