QToolBar中使用样式表QSS设置三态QToolButton按钮

QToolBar中设置三态QToolButton按钮

首先,我这个其实是模仿VS Code那个左侧菜单栏做的,看一下目标效果:在这里插入图片描述先分析一下,这是一个状态栏,由按钮组成,按钮有三个状态:正常(灰),鼠标悬浮(白),点击后(白+竖线)

这是最后的效果:
在这里插入图片描述我这个是不是模仿的很逼真?

需要准备的东西:

1.知道原VS code工具栏的背景色,是rgb(51,51,51);
2.准备好每个按钮的三态图片,我是从百度上挑的几张按钮图标,再使用PhotoShop进行颜色变化,背景透明处理,白色竖线添加,拿一个图标举例如下:
正常状态:
edit_normal,正常状态点击后的状态(颜色比较浅,仔细看)
edit_pressed,点击后的状态鼠标悬浮状态(也是比较浅的颜色)
鼠标悬浮状态

这里来说一下实现思路:

1.选择QToolBar作为工具栏

2.至于按钮,这里选择QToolButton,
因为:(1):QToolButton没有边框,QPushButton有边框(虽然你可以设置为Flat,但那样也有很多麻烦),(2):QToolButton的QSS属性有一个叫border-image,可以在:hover等伪装态时修改,从而达到修改图标颜色的效果,但QPushButton的qproperty-icon这个QSS属性无法在伪装态的样式表中修改,只能调用相关接口,没有样式表简单.
结论就是用QToolButton实现,图标使用QSS的border-image属性来实现(这对于图像的要求比普通的icon要高,你要1.调整背景图片中实际图标的比例,这里涉及PS里的调整画布大小,2.每个状态中背景图片的图案的颜色,3.把背景图片的背景变透明)

3.设置正常状态和悬浮状态都是常规操作,这里不罗嗦,基础的QSS使用.但是点击后那个有点小问题,:pressed这个伪装态只能设置点击一瞬间的样式,如果你通过设置:pressed,效果是这样的:
在这里插入图片描述这里我看了一些别的博客,发现最后只能用信号来机制解决了,信号是工具栏上的按钮被点击clicked,那么槽函数呢?
要解决两个问题:(1):把上次点击的按钮恢复为正常状态的背景图片,(2)把被点击的按钮设置为点击状态的背景图片.
那怎么确定上次点击的按钮呢?难道还要再定义个变量chosen_button来确定?
还有,样式表每次都是覆盖式设置,你不能只设置部分控件的样式,只要setStyleSheet(),那就要所有都设置一遍.

解决方案1:直接在槽函数把所有控件重新设置一遍,简单粗暴.
上源码(里面还有一些小细节,QSS属性名称及值格式,函数接口注意点,建议看一看注释):

//获取工具栏;
    toolbar_v=addToolBar("");
    //因为我们不是用ui,所以要设置ObjectName来作为QSS用的id
    toolbar_v->setObjectName("toolbar_v");
    toolbar_v->setAllowedAreas(Qt::LeftToolBarArea);
    toolbar_v->setOrientation(Qt::Vertical);
    toolbar_v->setMovable(false);
    //设置最大宽度,要不然它总是expand
    toolbar_v->setMaximumWidth(123);
    toolbar_v->setMinimumHeight(1980);

    
    //资源管理器按钮
    manage=new QToolButton(this);
    //一定要设置ObjectName,否则没法用样式表
    manage->setObjectName("manage");

    //编辑按钮
    edit=new QToolButton(this);
    edit->setObjectName("edit");

    //主页按钮:
    home=new QToolButton(this);
    home->setObjectName("home");

    //设置按钮:
    set=new QToolButton(this);
    set->setObjectName("set");

    //添加到工具栏上
    toolbar_v->addWidget(manage);
    toolbar_v->addWidget(edit);
    toolbar_v->addWidget(home);
    toolbar_v->addWidget(set);

    //设置按下按钮的槽函数,这里先做了样式方面的设置:
    connect(manage,&QToolButton::clicked,[=](){
        setStyleSheet("QToolBar QToolButton{"
                      "color:white;"
                      "font-size:20px;"
                      "min-width:123px;"
                      "min-height:123px}"
                      ""
                      "#manage{"
                      "border-image: url(:/images/menu_pressed);}"
                      ""
                      "#edit{"
                      "border-image: url(:/images/edit_normal);}"
                      "#edit:hover{"
                      "border-image:url(:/images/edit_hover);}"
                      ""
                      "#home{"
                      "border-image: url(:/images/home_normal);}"
                      "#home:hover{"
                      "border-image:url(:/images/home_hover);}"
                      ""
                      "#set{"
                      "border-image: url(:/images/set_normal);}"
                      "#set:hover{"
                      "border-image:url(:/images/set_hover);}"
                      ""
                      "#toolbar_v{"
                      "background-color:rgb(51,51,51);}"
                      "");
    });
    connect(edit,&QToolButton::clicked,[=](){
        setStyleSheet("QToolBar QToolButton{"
                      "color:white;"
                      "font-size:20px;"
                      "min-width:123px;"
                      "min-height:123px}"
                      ""
                      "#manage{" //需要区分-和_,很容易搞混
                      "border-image: url(:/images/menu_normal);}"
                      "#manage:hover{"
                      "border-image:url(:/images/menu_hover);}"
                      ""
                      "#edit{"
                      "border-image: url(:/images/edit_pressed);}"
                      ""
                      "#home{"
                      "border-image: url(:/images/home_normal);}"
                      "#home:hover{"
                      "border-image:url(:/images/home_hover);}"
                      ""
                      "#set{"
                      "border-image: url(:/images/set_normal);}"
                      "#set:hover{"
                      "border-image:url(:/images/set_hover);}"
                      ""
                      "#toolbar_v{"
                      "background-color:rgb(51,51,51);}"
                      "");
    });
    connect(home,&QToolButton::clicked,[=]{
            this->hide();});
           //最后,设置一遍状态下的样式
             this->setStyleSheet("QToolBar QToolButton{"
                        "color:white;"
                        "font-size:20px;"
                        "min-width:123px;"
                        "min-height:123px}"
                        ""
                        "#manage{"
                        "border-image: url(:/images/menu_normal);}"
                        "#manage:hover{"
                        "border-image:url(:/images/menu_hover);}"
                        ""
                        "#edit{"
                        "border-image: url(:/images/edit_normal);}"
                        "#edit:hover{"
                        "border-image:url(:/images/edit_hover);}"
                        ""
                        "#home{"
                        "border-image: url(:/images/home_normal);}"
                        "#home:hover{"
                        "border-image:url(:/images/home_hover);}"
                        ""
                        "#set{"
                        "border-image: url(:/images/set_normal);}"
                        "#set:hover{"
                        "border-image:url(:/images/set_hover);}"
                        ""
                        "#toolbar_v{"
                        "background-color:rgb(51,51,51);}"
                        ""
                        );

这种方法解决这个问题是没有问题,但一些缺点很明显:
1.假如我的窗口还要设置其它控件的样式,那每次都重新复制粘贴,再修改目标段落,要求我要对整个样式表很清楚,但前面写的还要时刻记着浪费时间复习.
2.同样的,每次都要复制,粘贴,太占地方,复杂,降低了整个代码的可读性,所以:

解决方法2:对上一个方法的优化,可以减少代码行数,方便样式表的扩展.
我在主窗口类中定义一个globel_styleString的QString变量,用来储存总的样式字符串,
再定义一个函数:void add_styleString(QString partial_styleString);
每次我修改某个部分样式表,就调用该方法,传参为该部分的样式表字符串.
在该函数内部进行字符串拼接,将该部分字符串拼接至全局样式字符串中,然后在我的add_styleString()方法内部调用setStyleSheet()函数.
用这个方法,解决了控件扩展和控件更新的样式字符串更新问题.
代码如下:

类的头文件中相关部分定义和声明如下:

//一些成员变量
    QToolBar *toolbar_v=NULL;
        QString toolbar_v_styleString;
        QToolButton *manage =NULL;
        QToolButton *edit=NULL;
        QToolButton *home=NULL;
        QToolButton *set=NULL;
    QTabWidget *tabwidget=NULL;
    QTreeView *treeview=NULL;


    /*因为样式表字符串只能有一个,
     * 这里我采用拼接的方式,有一个总样式表,
     * 每次新添加样式表,就添加到总样式表字符串中
     * 最后直接设置总样式就行
    */
    QString globel_styleString="";
    //用来设置样式表的函数:
public:
    void add_styleString(QString);

该头文件对应cpp文件相关部分如下:

Note_MainWindow::Note_MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Note_MainWindow)
{
    ui->setupUi(this);
    //1301:工具栏准备工作
    //获取工具栏;
    toolbar_v=addToolBar("");
    //因为我们不是用ui,所以要设置ObjectName来作为QSS用的id
    toolbar_v->setObjectName("toolbar_v");
    toolbar_v->setAllowedAreas(Qt::LeftToolBarArea);
    toolbar_v->setOrientation(Qt::Vertical);
    toolbar_v->setMovable(false);
    //设置最大宽度,要不然它总是expand
    toolbar_v->setMaximumWidth(123);
    toolbar_v->setMinimumHeight(1980);


    //资源管理器按钮
    manage=new QToolButton(this);
    //一定要设置ObjectName,否则没法用样式表
    manage->setObjectName("manage");

    //编辑按钮
    edit=new QToolButton(this);
    edit->setObjectName("edit");

    //主页按钮:
    home=new QToolButton(this);
    home->setObjectName("home");

    //设置按钮:
    set=new QToolButton(this);
    set->setObjectName("set");

    //添加到工具栏上
    toolbar_v->addWidget(manage);
    toolbar_v->addWidget(edit);
    toolbar_v->addWidget(home);
    toolbar_v->addWidget(set);

    //设置按下按钮的槽函数,这里先做了样式方面的设置:
    connect(manage,&QToolButton::clicked,[=](){
        //因为实际中按下按钮保持效果的只有两个,所以我可以只重新说明这两个按钮的样式字符串就好
        add_styleString(
                      "#manage{"
                      "border-image: url(:/images/menu_pressed);}"
                      "#manage:hover{"
                      "border-image:url(:/images/menu_pressed);}"
                      ""
                      "#edit{"
                      "border-image: url(:/images/edit_normal);}"
                      "#edit:hover{"
                      "border-image:url(:/images/edit_hover);}");
    });
    connect(edit,&QToolButton::clicked,[=](){
        add_styleString(
                      "#manage{"
                      "border-image: url(:/images/menu_normal);}"
                      "#manage:hover{"
                      "border-image:url(:/images/menu_hover);}"
                      ""
                      "#edit{"
                      "border-image: url(:/images/edit_pressed);}"
                      "#edit:hover{"
                      "border-image:url(:/images/edit_pressed);}"
                      );
    });
    
    connect(home,&QToolButton::clicked,[=]{
            this->hide();});
    
    //这个是toolbar的基础样式字符串
    QString basic_toolbar_styleString="QToolBar QToolButton{"
                                      "color:white;"
                                      "font-size:20px;"
                                      "min-width:123px;"
                                      "min-height:123px}"
                                      ""
                                      "#manage{"
                                      "border-image: url(:/images/menu_normal);}"
                                      "#manage:hover{"
                                      "border-image:url(:/images/menu_hover);}"
                                      "#manage:pressed{"
                                      "border-image:url(:/images/menu_pressed);}"
                                      ""
                                      "#edit{"
                                      "border-image: url(:/images/edit_normal);}"
                                      "#edit:hover{"
                                      "border-image:url(:/images/edit_hover);}"
                                      "#edit:pressed{"
                                      "border-image:url(:/images/edit_pressed);}"
                                      ""
                                      "#home{"
                                      "border-image: url(:/images/home_normal);}"
                                      "#home:hover{"
                                      "border-image:url(:/images/home_hover);}"
                                      ""
                                      "#set{"
                                      "border-image: url(:/images/set_normal);}"
                                      "#set:hover{"
                                      "border-image:url(:/images/set_hover);}"
                                      ""
                                      "#toolbar_v{"
                                      "background-color:rgb(51,51,51);}"
                                      "";
    add_styleString(basic_toolbar_styleString);
    //1301:工具栏准备工作完成



}

//设置样式表的函数,只要样式表有变化,就调用该方法
//直接将改变部分的样式字符串传进来就好
void Note_MainWindow::add_styleString(QString partial_styleString){
    globel_styleString+=partial_styleString;
    this->setStyleSheet(globel_styleString);

}

Note_MainWindow::~Note_MainWindow()
{
    delete ui;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章