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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章