一、展示效果
二、内容分析
载体:QScrollArea
单元项:QVBoxLayout
头部窗体:QWidget
item容器:QListWidget(QListView::IconMode)
头部标题:QToolButton
头部按钮:QPushButton
原理:载体包含多个单元项,单元项包含头部窗体与item容器,头部窗体包含头部标题与头部按钮,中间使用弹簧隔开。
三、内容实现
1、载体
新建一个QtGuiClass,在其ui内添加QScrollArea,布局后设置周围边界间距为0
初始化载体
//.h
struct DrawerItem
{
DrawerItem() {};
std::string label;
QPushButton *pushButton;
QToolButton *toolButton;
QListWidget *widget;
};QString m_strUpIcon, m_strDownIcon;//icon路径
std::vector<DrawerItem> m_vecDrawerItem;QVBoxLayout *m_pScrollAreaLayout;
//.cpp
m_pScrollAreaLayout = new QVBoxLayout(ui.scrollArea->widget());//为了使其自动显示滚动条
m_pScrollAreaLayout->setContentsMargins(0, 0, 0, 0);
m_pScrollAreaLayout->setSpacing(1);
AddUnitItem(u8"图像采集"); //添加单元项
AddUnitItem(u8"图像采集");
m_pScrollAreaLayout->addStretch(1);//弹簧QString strStyleSheet(R"(QWidget{
border:none;
background-color: rgb(100, 100, 100);
})");
this->setStyleSheet(strStyleSheet);
2、头部窗体
QString strLabel = " "+QString::fromStdString(label);//加空格为了解决图标和文字之间的间距
//头部布局
QHBoxLayout *hLayout = new QHBoxLayout();
hLayout->setContentsMargins(5, 0, 0, 0);DrawerItem item;
item.label = label;
//头部右侧按钮
QString strPushBottonStyleSheet(R"(QPushButton{
border:none;
background-color: rgb(150, 150, 150);
}
)");
item.pushButton = new QPushButton(this);
connect(item.pushButton, &QPushButton::clicked, this, &DrawerWidget::SlotPushButtonClicked);
item.pushButton->setProperty("index", m_vecDrawerItem.size());
item.pushButton->setFixedSize(30, 30);
item.pushButton->setStyleSheet(strPushBottonStyleSheet);
item.pushButton->setIcon(QIcon(":/Qss/down.png"));//头部左侧按钮 /*padding-left:0px; 取消点击下沉效果*/
QString strToolBottonStyleSheet(R"(QToolButton{
padding-left:0px;
border:none;
background-color:rgb(150, 150, 150);
}
)");item.toolButton = new QToolButton(this);
//item.toolButton->setAutoRaise(false);
item.toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
item.toolButton->setText(strLabel );
item.toolButton->setFixedSize(80, 30);
item.toolButton->setProperty("index", m_vecDrawerItem.size());
item.toolButton->setStyleSheet(strToolBottonStyleSheet);
item.toolButton->setIcon(QIcon(m_strDownIcon));//头部布局添加item
hLayout->addWidget(item.toolButton);
hLayout->addStretch(1);//弹簧
hLayout->addWidget(item.pushButton);//头部布局窗体
QWidget *topWidget = new QWidget();
topWidget->setLayout(hLayout);
topWidget->setStyleSheet("background-color: rgb(150, 150, 150)"); //设置背景色
SlotPushButtonClicked
void DrawerWidget::SlotPushButtonClicked()
{
QPushButton *button = qobject_cast<QPushButton *>(sender());
int index = button->property("index").toInt();
bool bVisible = m_vecDrawerItem[index].widget->isVisible();
for (auto item:m_vecDrawerItem)
{
item.widget->setVisible(false);
}
m_vecDrawerItem[index].widget->setVisible(!bVisible);
m_vecDrawerItem[index].pushButton->setIcon(QIcon(bVisible ? m_strDownIcon : m_strUpIcon));
}
3、item容器
item.widget = new QListWidget;
item.widget->setViewMode(QListView::IconMode);
item.widget->setFixedSize(QSize(240, 297));
item.widget->setVisible(false);/* 设置为列表显示模式 */
item.widget->setIconSize(QSize(67, 67));//设置单个Icon大小
item.widget->setSpacing(3);//设置缩略图间距
//item.widget->setFlow(QListView::TopToBottom);//从左到右
item.widget->setResizeMode(QListView::Adjust);//大小自适应
item.widget->setMovement(QListView::Static);//设置列表每一项不可移动
/* 屏蔽水平滑动条 */
item.widget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
/* 屏蔽垂直滑动条 */
item.widget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
/* 设置为像素滚动 */
item.widget->setHorizontalScrollMode(QListWidget::ScrollPerPixel);
//ui.listWidget->scrollToBottom();//保持始终展示滚动条的最后一个item ,对/* 设置鼠标左键拖动 */
//QScroller::grabGesture(item.widget, QScroller::LeftMouseButtonGesture);
//样式表设计
item.widget->setStyleSheet("QListWidget{color:black;outline:0px; }"
"QListWidget::Item{padding-left:1px;padding-right:1px;padding-top:3px; padding-bottom:3px;color:black}"
//"QListWidget::Item:hover{background:black; color:green;}"
//"QListWidget::item:selected{background:black; color:green; }"
);
AddListWidgetItem(item.widget);
添加item
void DrawerWidget::AddListWidgetItem(QListWidget *widget)
{
QIcon icon(u8":/VisionProgram/favicon.ico");QListWidgetItem *listItem = new QListWidgetItem(icon, "test");
listItem->setTextAlignment(Qt::AlignHCenter);//设置文字对齐方式:水平居中
widget->addItem(listItem);// 添加QListWidgetItem到QListWidget中
}
4、单元项
//单个单元垂直布局添加头部窗体和listWidget窗体
QVBoxLayout *vLayout = new QVBoxLayout();
vLayout->addWidget(topWidget);
vLayout->addWidget(item.widget);//ScrollArea布局添加单个单元布局
m_pScrollAreaLayout->addLayout(vLayout);
m_vecDrawerItem.emplace_back(item);
四、问题
1、QScrollArea自动出现滚动条
方法:
ui.scrollArea->setWidgetResizable(true);//使幕布随着scrollArea自动改变大小
//ui.scrollArea->widget()->setFixedSize(QSize(288, 500));
m_pScrollAreaLayout = new QVBoxLayout(ui.scrollArea->widget());
/*
m_pScrollAreaLayout添加不同的控件
*/
注意:是ui.scrollArea->widget()而不是ui.scrollArea,ui.scrollArea本身只是一个视窗,在UI拖拽一个scrollArea会自动创建一个幕布scorllAreaWidgetContents就是ui.scrollArea->widget(),只有幕布控件scorllAreaWidgetContents的大小超过了QScrollArea的大小,才会自动出现滚动条;如果没有ui.scrollArea->setWidgetResizable(true),则需要手动修改幕布大小;所以当m_pScrollAreaLayout添加的控件尺寸超过ui.scrollArea时,就会自动出现滚动条,如果不想出现滚动条改为m_pScrollAreaLayout = new QVBoxLayout(ui.scrollArea);或者如果new时不指定父类,则后面需要添加ui.scrollArea->setLayout(m_pScrollAreaLayout)。
2、QToolButton图标与文字之间间距
直接在文字前加了空格” “,网上的方法都没测试成功,不知道什么问题,需要继续探索。
3、QScrollArea的滚动条样式
//设置ui.scrollArea滚动条宽度,直接在样式表使用,不起作用,但是如果使用qss文件加载就可以
QString strQScrollBarStyleSheet(R"(ScrollBar:vertical {
border: none;
border-radius: 2px;
background: rgb(66, 66, 66);
}
QScrollBar::handle:vertical {
background: rgb(66, 66, 66);
min-height: 20px;
border-radius: 2px;
border: none;
}
/* 鼠标滑过滑块样式 */
QScrollBar::handle:vertical:hover,
QScrollBar::handle:vertical:pressed {
background: rgb(85, 85, 85);
}
/*上下进度条背景色 滚动条上下的颜色*/
QScrollBar::sub-page:vertical {
background: rgb(30, 30, 30);
}
QScrollBar::add-page:vertical
{
background: rgb(30, 30, 30);
}
/*在上面设置width不起作用,可能是被下面布局覆盖了*/
QScrollBar:vertical { width: 8px;}
)");
ui.scrollArea->setStyleSheet(strQScrollBarStyleSheet);
注意:需要单独写一次QScrollBar:vertical { width: 8px;},如果width:8px;直接写在上面vertical{}中,不起作用,不知道原因,可能是被下面的演示表覆盖了;
PS:小课堂
样式表知识点:1:样式表直接写成qss文件,然后读取文件加载;2:写成字符串QString,再设置;3:直接在UI内右击->改变样式表,在其中添加样式表;
1就是可以重复利用,下次直接加载就可以了,3好处是帮你检验样式表是否有效,如果无效它左下角会提示;2使用QString sheet(R"())直接在最里面小括号内添加样式表,这样格式和1、3通用,否则每写一个属性就要加双引号。
待续。。。