1 效果展示
2 Button包含图文的不同方向
使用描述
如上图所示,在使用过程中,我们需要设置不同方向上的文字和图片,要达到这种效果在qt中有多种方法,有可以使用qss直接设置实现的,本文主要采用继承QPushButton类来实现不同方向上的文字。
2.1 采用的思想和代码介绍
1、本文采用的思想是继承于QPushButton,利用QLabel来设置文字和图片,然后使用QBoxLayout来实现不同方向上的位置,QBoxLayout是QT中的布局设置,包含垂直布局和水平布局,它有四个方向,根据不同方向来选择QHBoxLayout(水平布局) 和QHBoxLayout(垂直布局)。
//QHBoxLayout
case QBoxLayout::LeftToRight:
case QBoxLayout::RightToLeft:
//QVBoxLayout
case QBoxLayout::TopToBottom:
case QBoxLayout::BottomToTop:
主要的代码如下
BasicIconTextBtn::BasicIconTextBtn(QWidget *parent,QBoxLayout::Direction dir):BasicButton(parent)
{
//根据传入的位置设置布局
initLayout(dir);
//初始化TextLabel和IconLabel
iconLab = new QLabel(this);
textLab = new QLabel(this);
distanceItem = new QSpacerItem(10,10,QSizePolicy::Fixed,QSizePolicy::Fixed);
iconLab->setAlignment(Qt::AlignCenter);
iconLab->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
textLab->setAlignment(Qt::AlignCenter);
textLab->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
getNextPos(dir, row, colum);
//将文字和图片控件装进布局里面,布局会自动排列,并在这里添加了QSpacerItem,来控制文字和图片之间的间距
layout->addItem(new QSpacerItem(0,0,QSizePolicy::Expanding,QSizePolicy::Expanding));
if(dir == QBoxLayout::BottomToTop || dir == QBoxLayout::RightToLeft){
layout->addWidget(textLab);
layout->addItem(distanceItem);
layout->addWidget(iconLab);
}else{
layout->addWidget(iconLab);
layout->addItem(distanceItem);
layout->addWidget(textLab);
}
layout->addItem(new QSpacerItem(0,0,QSizePolicy::Expanding,QSizePolicy::Expanding));
layout->setSpacing(0);
layout->setContentsMargins(0,0,0,0);
this->setLayout(layout);
}
3 完整的基类代码
BasicButton.h
#include <QPushButton>
#include <QStylePainter>
#include <QStyleOptionButton>
#include <QLayout>
#include <QLabel>
class BasicButton : public QPushButton
{
Q_OBJECT
public:
explicit BasicButton(QWidget *parent = nullptr);
protected:
void paintEvent(QPaintEvent *);
};
class BasicIconTextBtn : public BasicButton
{
Q_OBJECT
public:
explicit BasicIconTextBtn(QWidget *parent = nullptr, QBoxLayout::Direction dir = QBoxLayout::LeftToRight);
void setIconSize(QString iconPath, int width, int height);
void setTextFont(QString text, QFont &font);
void setDistance(int distance);
void setTextStyle(QString style);
private:
void getNextPos(QBoxLayout::Direction dir, int &row, int &colum);
void initLayout(QBoxLayout::Direction dir);
protected:
QPixmap pix;
QLabel *iconLab;
QLabel *textLab;
QSpacerItem *distanceItem;
QLayout *layout;
};
BasicButton.cpp
BasicButton::BasicButton(QWidget *parent) : QPushButton(parent)
{
}
void BasicButton::paintEvent(QPaintEvent *)
{
//Set the style of painting as a button and make it have some properties of the button
QStylePainter p(this);
QStyleOptionButton option;
initStyleOption(&option);
p.drawControl(QStyle::CE_PushButton, option);
}
BasicIconTextBtn::BasicIconTextBtn(QWidget *parent,QBoxLayout::Direction dir):BasicButton(parent)
{
this->setCheckable(true);
int row = -1;
int colum = -1;
//根据传入的位置设置布局
initLayout(dir);
//初始化TextLabel和IconLabel
iconLab = new QLabel(this);
textLab = new QLabel(this);
distanceItem = new QSpacerItem(10,10,QSizePolicy::Fixed,QSizePolicy::Fixed);
iconLab->setAlignment(Qt::AlignCenter);
iconLab->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
textLab->setAlignment(Qt::AlignCenter);
textLab->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
getNextPos(dir, row, colum);
//将文字和图片控件装进布局里面,布局会自动排列,并在这里添加了QSpacerItem,来控制文字和图片之间的间距
layout->addItem(new QSpacerItem(0,0,QSizePolicy::Expanding,QSizePolicy::Expanding));
if(dir == QBoxLayout::BottomToTop || dir == QBoxLayout::RightToLeft){
layout->addWidget(textLab);
layout->addItem(distanceItem);
layout->addWidget(iconLab);
}else{
layout->addWidget(iconLab);
layout->addItem(distanceItem);
layout->addWidget(textLab);
}
layout->addItem(new QSpacerItem(0,0,QSizePolicy::Expanding,QSizePolicy::Expanding));
layout->setSpacing(0);
layout->setContentsMargins(0,0,0,0);
this->setLayout(layout);
}
void BasicIconTextBtn::setIconSize(QString iconPath, int width, int height)
{
pix.load(iconPath);
iconLab->setPixmap(pix);
//设置图片大小和是否填充满整个label,这里是保持原大小,不夸大填充
pix.scaled(QSize(width,height), Qt::KeepAspectRatio);
}
void BasicIconTextBtn::setTextFont(QString text, QFont &font)
{
//设置文字和字体大小
textLab->setText(text);
textLab->setFont(font);
}
void BasicIconTextBtn::setDistance(int distance)
{
//设置文字和图片之间的间隙,重载spacer
distanceItem->changeSize(distance, distance, QSizePolicy::Fixed,QSizePolicy::Fixed);
}
void BasicIconTextBtn::setTextStyle(QString style)
{
textLab->setStyleSheet(style);
}
void BasicIconTextBtn::getNextPos(QBoxLayout::Direction dir, int &row, int &colum)
{
if(row >= 0 && colum >=0)
{
switch(dir)
{
case QBoxLayout::LeftToRight:
colum++;
break;
case QBoxLayout::RightToLeft:
colum--;
break;
case QBoxLayout::TopToBottom:
row++;
break;
case QBoxLayout::BottomToTop:
row--;
break;
}
}
else
{
switch(dir)
{
case QBoxLayout::LeftToRight:
case QBoxLayout::TopToBottom:
row = 0;
colum = 0;
break;
case QBoxLayout::RightToLeft:
row = 0;
colum = 4;
break;
case QBoxLayout::BottomToTop:
row = 4;
colum = 0;
break;
}
}
}
void BasicIconTextBtn::initLayout(QBoxLayout::Direction dir)
{
switch(dir)
{
case QBoxLayout::LeftToRight:
case QBoxLayout::RightToLeft:
layout = new QHBoxLayout();
break;
case QBoxLayout::TopToBottom:
case QBoxLayout::BottomToTop:
layout = new QVBoxLayout();
break;
default:
// qDebug()<<"out of range";
layout = new QHBoxLayout();
break;
}
}
调用上面的基类就可以实现QPushButton的图片和文字的不同方向和位置设置了,并且不影响QPushButton的信号和槽的使用。
温馨提醒 !!!:
其中的文字颜色和字体设置可以调用setTextStyle(QString style);方法来设置,由于其中的图片和文字是调用QLabel设置的,所以如果在QSS文件中设置QPushButton的样式,是无法设置图片和文字的样式的,但是可以设置QPushButton的border和backgroud。