Qt|QToolBtton实现三态图标及文字变化

效果:
Qt|QToolBtton实现三态图标及文字变化_第1张图片

第一种方法使用原生QToolButton的stylesheet实现,优点很明显代码量少,也可灵活修改。

// 设置样式。背景图,置顶,居中,无伸缩;字体大小;上面空出36px给图片;
QString button_style = "QToolButton {background:url(:/normal.png) top center no-repeat; font-size:12px; padding-top:36px;font-family:Microsoft YaHei; color:rgb(0,0,0); border:none;}\
QToolButton:hover {background:url(:/normal.png) top center no-repeat; font-size:12px; padding-top:36px;font-family:Microsoft YaHei; color:rgb(0,0,0); border:none;}\
QToolButton:pressed {background:url(:/normal.png) top center no-repeat; font-size:12px; padding-top:36px;font-family:Microsoft YaHei; color:rgb(0,0,0); border:none;}\"
QToolButton* tool_button = new QToolButton;
tool_button->setStyleSheet(button_style);
tool_button->setFixedSize(36,53);
tool_button->setIconSize(QSize(36,36));
tool_button->setText(QStringLiteral("导出"));
tool_button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
//设置QToolButton按钮自动弹起
tool_button->setAutoRaise(true);

第二种方法重写QToolButton类,方便多次使用,每次创建只需要传一个QAaction,面对对象概念。
头文件:

#pragma once

#include 
#include
#include
#include
#include

class MyToolButton : public QToolButton
{
    Q_OBJECT

public:
    MyToolButton(QWidget *parent = Q_NULLPTR);

	// 为了让button根据文字长度自适应大小居中
	// 这里有一个坑,如果初始化的时候设置了最小大小等,它就不起作用了
	virtual QSize sizeHint() const override;

protected:
	virtual void paintEvent(QPaintEvent* event) override;
};

源文件:

#include "MyToolButton.h"

MyToolButton::MyToolButton(QWidget *parent)
    : QToolButton(parent)
{
}

QSize MyToolButton::sizeHint() const
{
    // 设置默认值
    QSize width_text(48, 53);
    // 获取字长度
    QFontMetrics fontMetrics(font());
    // 获取之前一定要判断有没有设置action
    if (this->defaultAction() == nullptr)
        return width_text;
    int width = fontMetrics.width(this->defaultAction()->text());
    // 如果文字太少宽度不够图片会显示不全
    // 这里设置的图标大小为36,可优化为任意大小,根据qt的函数灵活获取图片大小设置
    width_text.setWidth(width < 36 ? 36 : width);
    return width_text;
}

void MyToolButton::paintEvent(QPaintEvent* event)
{
    if (this->defaultAction() == nullptr)
        return;

    QPainter p(this);
    // 获取toolbutton状态
    QStyleOptionToolButton option;
    initStyleOption(&option);
    const bool enabled = option.state & QStyle::State_Enabled;      // 可用
    //const bool checked = option.state & QStyle::State_On;         // 选中(没有使用这个状态)
    const bool selected = option.state & QStyle::State_MouseOver;   // 滑过
    const bool pressed = option.state & QStyle::State_Sunken;       // 按下
    // 绘制图标
    QPixmap pix(36, 36);
    // 不同状态不同图片
    if (pressed) {
        pix = this->defaultAction()->icon().pixmap(36, 36, QIcon::Selected, QIcon::Off);
    }
    else if (selected) {
        pix = this->defaultAction()->icon().pixmap(36, 36, QIcon::Active, QIcon::Off);
    }
    else if (enabled) {
        pix = this->defaultAction()->icon().pixmap(36, 36, QIcon::Normal, QIcon::Off);
    }
    QPixmap img(pix);
    if (!pix.isNull()) {
        p.drawPixmap(this->width() / 2 - 18, 0, 36, 36, img);
    }
    // 绘制文字
    QRect text_rect = this->rect().adjusted(0, 36, 0, 0);
    QColor colorText;
    if (pressed) {
        colorText = QColor(0, 0, 0);
    }
    else if (selected) {
        colorText = QColor(0, 0, 0);
    }
    else if (enabled) {
        colorText = QColor(111, 111, 111);
    }
    QFont text_font;
    text_font.setFamily("Microsoft YaHei");
    text_font.setPixelSize(12);
    p.setFont(text_font);
    p.setPen(QPen(colorText));
    p.drawText(text_rect, Qt::AlignHCenter, this->defaultAction()->text());
}

主函数:

#include "MyToolButton.h"
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QIcon icon;
    // 这里还有一个坑记录一下,一开始用的qrc文件设置图标设置不上,因为电脑没有配置qt的环境变量,会影响qrc编译
    //QCoreApplication::applicationDirPath() + "/../..
    icon.addPixmap(QPixmap(":/MyToolButton/res/normal.png"), QIcon::Normal, QIcon::Off);
    icon.addPixmap(QPixmap(QCoreApplication::applicationDirPath() + "/../../MyToolButton/res/hover.png"), QIcon::Active, QIcon::Off);
    icon.addPixmap(QPixmap(QCoreApplication::applicationDirPath() + "/../../MyToolButton/res/pressed.png"), QIcon::Selected, QIcon::Off);
    QAction* action = new QAction;
    action->setIcon(icon);
    action->setText(QStringLiteral("哈哈哈哈哈测试一下长度"));
    MyToolButton* my_button = new MyToolButton;
    my_button->setDefaultAction(action);
    QWidget* test_widget = new QWidget;
    test_widget->setMinimumSize(200, 200);
    QHBoxLayout* kk = new QHBoxLayout;
    kk->addWidget(my_button);
    test_widget->setLayout(kk);
    test_widget->show();

    return a.exec();
}

你可能感兴趣的:(C/C++/qt,c++,qt)