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