抽屉效果工具窗

 一、展示效果

  二、内容分析

载体: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通用,否则每写一个属性就要加双引号。

待续。。。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值