近来把刘典武大神在gitee上的程序下载下来了。
看到了一个自定义按钮类navbutton,蛮不错的。
比起原有的QPushButton,又提供了更多的功能,接口也比较便利。
quint32 size = 15;
quint32 pixWidth = 15;
quint32 pixHeight = 15;
//从图形字体获得图片,也可以从资源文件或者路径文件获取
int icon = 0xf061;
QPixmap iconNormal = IconHelper::getPixmap(QColor(100, 100, 100).name(), icon, size, pixWidth, pixHeight);
QPixmap iconHover = IconHelper::getPixmap(QColor(255, 255, 255).name(), icon, size, pixWidth, pixHeight);
QPixmap iconCheck = IconHelper::getPixmap(QColor(255, 255, 255).name(), icon, size, pixWidth, pixHeight);
btns1 << ui->navButton11 << ui->navButton12 << ui->navButton13 << ui->navButton14;
for (int i = 0; i < btns1.count(); i++) {
NavButton *btn = btns1.at(i);
btn->setPaddingLeft(32);
btn->setLineSpace(6);
btn->setShowIcon(true);
btn->setIconSpace(15);
btn->setIconSize(QSize(10, 10));
btn->setIconNormal(iconNormal);
btn->setIconHover(iconHover);
btn->setIconCheck(iconCheck);
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClick1()));
}
里面还用到了一个iconhelper类,这个类主要用来提供文字图形,也不错
我之前都是先下载下来图片,然后保存到qss,然后再用。
现在可以尝试用这种方式得到对应的QPixmap对象了。
不过为了方便查找对应的图形字体编号,可以在他的程序里查找,也有对应的图片,可以从图片中查找。
借助iconhelper,我们可以方便地获得对应图片文字的QPixmap,
可以设置图片颜色,大小,宽,高,位置。
static QPixmap getPixmap(const QColor &color, int icon, quint32 size = 12,
quint32 width = 15, quint32 height = 15,
int flags = Qt::AlignCenter);
感觉iconhelper类挺有意思的,这里进行分析:
(我就很想知道它怎么拥有那么多图形字体的)
我们调用该方法获得QPixmap:
QPixmap iconNormal = IconHelper::getPixmap(QColor(100, 100, 100).name(), icon, size, pixWidth, pixHeight);
这是它的原型:
QPixmap IconHelper::getPixmap(const QColor &color, int icon, quint32 size,
quint32 width, quint32 height, int flags)
{
return getIconHelper(icon)->getPixmap1(color, icon, size, width, height, flags);
}
又用到了方法:getIconHelper(icon)
原型为:
IconHelper *IconHelper::getIconHelper(int icon)
{
initFont();
//指定了字体索引则取对应索引的字体类
//没指定则自动根据不同的字体的值选择对应的类
//由于部分值范围冲突所以可以指定索引来取
//fontawesome 0xf000-0xf2e0
//fontawesome6 0xe000-0xe33d 0xf000-0xf8ff
//iconfont 0xe501-0xe793 0xe8d5-0xea5d 0xeb00-0xec00
//weather 0xe900-0xe9cf
IconHelper *iconHelper = iconFontAwesome;
if (iconFontIndex < 0) {
if ((icon >= 0xe501 && icon <= 0xe793) || (icon >= 0xe8d5 && icon <= 0xea5d) || (icon >= 0xeb00 && icon <= 0xec00)) {
iconHelper = iconFontAliBaBa;
}
} else if (iconFontIndex == 0) {
iconHelper = iconFontAliBaBa;
} else if (iconFontIndex == 1) {
iconHelper = iconFontAwesome;
} else if (iconFontIndex == 2) {
iconHelper = iconFontAwesome6;
} else if (iconFontIndex == 3) {
iconHelper = iconFontWeather;
}
return iconHelper;
}
这里根据icon的值得到对应的iconHelper:
一共有4种划分:
//阿里巴巴图形字体类
static IconHelper *iconFontAliBaBa;
//FontAwesome图形字体类
static IconHelper *iconFontAwesome;
//FontAwesome6图形字体类
static IconHelper *iconFontAwesome6;
//天气图形字体类
static IconHelper *iconFontWeather;
这里面又有一个方法:initFont()
void IconHelper::initFont()
{
static bool isInit = false;
if (!isInit) {
isInit = true;
if (iconFontAliBaBa == 0) {
iconFontAliBaBa = new IconHelper(":/font/iconfont.ttf", "iconfont");
}
if (iconFontAwesome == 0) {
iconFontAwesome = new IconHelper(":/font/fontawesome-webfont.ttf", "FontAwesome");
}
if (iconFontAwesome6 == 0) {
iconFontAwesome6 = new IconHelper(":/font/fa-regular-400.ttf", "Font Awesome 6 Pro Regular");
}
if (iconFontWeather == 0) {
iconFontWeather = new IconHelper(":/font/pe-icon-set-weather.ttf", "pe-icon-set-weather");
}
}
}
这里对4个静态的iconHelper对象进行初始化。
这是关键的构造语句:
iconFontAliBaBa = new IconHelper(":/font/iconfont.ttf", "iconfont");
IconHelper::IconHelper(const QString &fontFile, const QString &fontName, QObject *parent) : QObject(parent)
{
//判断图形字体是否存在,不存在则加入
QFontDatabase fontDb;
if (!fontDb.families().contains(fontName) && QFile(fontFile).exists()) {
int fontId = fontDb.addApplicationFont(fontFile);
QStringList listName = fontDb.applicationFontFamilies(fontId);
if (listName.size() == 0) {
qDebug() << QString("load %1 error").arg(fontName);
}
}
//再次判断是否包含字体名称防止加载失败
if (fontDb.families().contains(fontName)) {
iconFont = QFont(fontName);
#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0))
iconFont.setHintingPreference(QFont::PreferNoHinting);
#endif
}
}
对应的都是后缀为.ttf的文件。
存在QFontDatabase对象。
if (!fontDb.families().contains(fontName) && QFile(fontFile).exists())
大概就是如果数据库不包含名为fontName的families,同时路径为fontFile的文件存在,,,,,
int fontId = fontDb.addApplicationFont(fontFile);
QStringList listName = fontDb.applicationFontFamilies(fontId);
(这些都是我陌生的知识领域了)
回到最初的函数调用:
在获取了对应的iconhelper对象后,调用getPixmap1(color, icon, size, width, height, flags);
QPixmap IconHelper::getPixmap1(const QColor &color, int icon, quint32 size,
quint32 width, quint32 height, int flags)
{
//主动绘制图形字体到图片
QPixmap pix(width, height);
pix.fill(Qt::transparent);
QPainter painter;
painter.begin(&pix);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
painter.setPen(color);
iconFont.setPixelSize(size);
painter.setFont(iconFont);
painter.drawText(pix.rect(), flags, (QChar)icon);
painter.end();
return pix;
}
这里其实是把图形文字画在了QPixmap对象上。(drawText)
同时,根据iconFont.setPixelSize(size),说明size对应图形文字的大小。
(ps:感觉到了这个类的严谨和精美)
关于navbutton:
btn->setPaddingLeft(40);//文字左侧间隔
btn->setLineSpace(8);//线条间隔
btn->setShowIcon(true);
btn->setIconSpace(20);//图标间隔
btn->setIconSize(QSize(15, 15));//图标大小
btn->setIconNormal(iconNormal);
btn->setIconHover(iconHover);
btn->setIconCheck(iconCheck);
这些接口的详细含义:还是需要再好好了解一下。
其实比较容易理解:
考虑线条位置,图标位置,文字位置。
QRect textRect = QRect(paddingLeft, paddingTop, width() - paddingLeft - paddingRight, height() - paddingTop - paddingBottom);//文字位置
painter->drawPixmap(iconSpace, (height() - iconSize.height()) / 2, pix);
//图标
if (linePosition == LinePosition_Left) {
pointStart = QPoint(0, 0);
pointEnd = QPoint(0, height());
}//线条位置都在最边边
考虑矩形大小
if (linePosition == LinePosition_Left) {
bgRect = QRect(lineSpace, 0, width - lineSpace, height);
}