前言
我想实现一个左侧的上下的Tab分栏功能,看了Qt官方的文档好像没有合适的解决方案,于是自己自定义了一个
介绍
在上位机开发中,如果想要做一个侧边栏点击切换分页的功能,大家都想到用一组QPushButton
和自定义的QWidget
来做

然后我们用样式表修饰QPushButton
,同时用QWidget
自定一些Pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| QPushButton { font-size: 18px; / color: white; background-color: rgb(10,88,163); border: 2px solid rgb(114,188,51); text-align: left; padding-left: 10px; font-weight: bold; }
QPushButton:focus { background-color: rgb(41,51,57); color: rgb(114,188,51); border-width: 4px; }
|
用信号和槽把Buttons
和Pages
绑定起来,很快,一个切换分栏的用户界面就大功告成了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| connect(ui->button1, &QPushButton::clicked, this, [=]() { page1->setVisible(true); });
connect(ui->button2, &QPushButton::clicked, this, [=]() { page2->setVisible(true); });
connect(ui->button3, &QPushButton::clicked, this, [=]() { page3->setVisible(true); });
connect(ui->button4, &QPushButton::clicked, this, [=]() { page4->setVisible(true); });
|
问题
这样做的思路并没有错,但是会遇到一些问题,就是Pages
里边如果有一些强焦点属性的控件,很容易把左侧栏的Buttons
焦点拿走,导致focus
样式失效!问题的关键在于侧边栏和分页是在同一个界面下的,Buttons
的焦点是很容易丧失的

解决
引入QButtonGroup
功能,确保每个Button都是exclusive
的
1 2 3 4 5 6 7 8
| m_group = new QButtonGroup(this); m_group->setExclusive(true); m_group->addButton(ui->alarm); m_group->addButton(ui->operate); m_group->addButton(ui->communication); m_group->addButton(ui->systemLearn); m_group->addButton(ui->conductanceCurves); m_group->addButton(ui->about);
|
在Button切换焦点的时候变更样式,捕获QButtonGroup
的buttonClicked
信号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| connect(m_group, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), [=](QAbstractButton *button){ for(auto &but : m_group->buttons()) { if(button != but) { but->setStyleSheet("QPushButton { font-size: 18px;\ color: white;\ background-color: rgb(10,88,163);\ border: 2px solid rgb(114,188,51);\ text-align: left;\ padding-left: 10px;\ font-weight: bold;}"); } else { but->setStyleSheet("QPushButton { font-size: 18px;\ color: rgb(114,188,51);\ background-color: rgb(41,51,57);\ border: 4px solid rgb(114,188,51);\ text-align: left;\ padding-left: 10px;\ font-weight: bold;}"); } } });
|
直接不要样式表里边的focus
属性了,大致的实现效果如下

当然,要记得默认一个最开始的Button
1 2 3 4 5 6 7 8
| ui->operate->setFocus(); ui->operate->setStyleSheet("QPushButton { font-size: 18px;\ color: rgb(114,188,51);\ background-color: rgb(41,51,57);\ border: 4px solid rgb(114,188,51);\ text-align: left;\ padding-left: 10px;\ font-weight: bold;}");
|
总结
样式表能解决大部分问题,但是一些边边角角的东西需要自己琢磨(写C++代码)实现