Qt中使用QToolBox实现抽屉效果

原创
2015/05/22 12:57
阅读数 4.8K
#ifndef DRAWER_HPP
#define DRAWER_HPP

#include <QToolBox>
#include <QLayout>
#include "listwidget.hpp"
#include "listwidgetitem.hpp"

class Drawer : public QToolBox
{
    Q_OBJECT
public:
    Drawer(const QIcon &iconOpen, const QIcon &iconClose, QWidget *parent = 0,Qt::WindowFlags f = 0);

    void setSpacing(int value) {
        layout()->setSpacing(value);
    }

    /**
     * @brief addErea 在drawer中开辟一块区域
     * @param lable
     */
    void addErea(const QString &label);
    /**
     * @brief addEreaElem 向指定的区域中添加一个元素
     * @param _index 区域下标 从零开始
     * @param item 元素
     */
    void addEreaElem(int _index, QListWidgetItem *item);

    /**
     * @brief addEreaElem 向指定的区域中添加一个元素
     * @param _index 区域名称 
     * @param item 元素
     */
    void addEreaElem(const QString &label, QListWidgetItem *item);


signals:
    /**
     * @brief sig_click 那个区域的那个元素被点击
     * @param ereaIndex 区域下标
     * @param elemIndex 元素下标
     */
    void sig_click(int ereaIndex, int elemIndex);
public slots:

private slots:
    void slt_elemClick(QModelIndex _index);

    /**
     * @brief slt_currentIndexActive 当前的那个区域是活动的,来来改变图标
     * @param _index
     */
    void slt_currentIndexActive(int _index);
private:
    /**
     * @brief openIcon 
     */
    QIcon openIcon;
    /**
     * @brief closeIcon
     */
    QIcon closeIcon;
    /**
     * @brief preIndex 前一个活动区域的下标
     */
    int preIndex;

    QMap<QString,QListWidget*> ereaLabels;



    
};

#endif // DRAWER_HPP



#include "drawer.hpp"

Drawer::Drawer(const QIcon &iconOpen, const QIcon &iconClose, QWidget *parent, Qt::WindowFlags f) :
    QToolBox(parent, f),
    openIcon(iconOpen),
    closeIcon(iconClose),
    preIndex(-1)
{
    connect(this,SIGNAL(currentChanged(int)),this,SLOT(slt_currentIndexActive(int)));
}

void Drawer::slt_currentIndexActive(int _index)
{
    if (preIndex != -1) {
        setItemIcon(preIndex,closeIcon);
    }
    setItemIcon(_index,openIcon);
    preIndex = _index;
}

void Drawer::addErea(const QString &label)
{
    if (!ereaLabels.contains(label)) {
        ListWidget *erea = new ListWidget();
        connect(erea,SIGNAL(clicked(QModelIndex)),this,SLOT(slt_elemClick(QModelIndex)));
        int index = addItem(static_cast<QWidget*>(erea),label);
        setItemIcon(index,openIcon);
        ereaLabels.insert(label,erea);
    }

}

void Drawer::addEreaElem(const QString &label, QListWidgetItem *item)
{
    if (ereaLabels.contains(label)) {
        QListWidget *w = ereaLabels[label];
        w->addItem(item);
    } else {
        delete item;
    }
}

void Drawer::addEreaElem(int _index, QListWidgetItem *item)
{
    QWidget *w  = widget(_index);
    if (w) {
        static_cast<QListWidget*>(w)->addItem(item);
    }

}

void Drawer::slt_elemClick(QModelIndex _index)
{
    int i = _index.row();
    QWidget * w = static_cast<QWidget*> (sender());
    int j = indexOf(w);
    emit sig_click(j,i);
}



其中继承了QListWidget和QListWIdgetItem来提供一些特殊的实现,不过演示的时候没有用。

还有一个问题就是QListWidget除了项之外,还有好多的空白项



代码:http://www.kuaipan.cn/file/id_45404676266394511.htm



修复一个bug

void Drawer::addErea(const QString &label)
{
    if (!ereaLabels.contains(label)) {
        ListWidget *erea = new ListWidget();
        connect(erea,SIGNAL(clicked(QModelIndex)),this,SLOT(slt_elemClick(QModelIndex)));
        int index = addItem(static_cast<QWidget*>(erea),label);//当添加第一个时,回触发currentChanged信号,再回到这里时,图标为close,其实是open
        if (index != 0) {
            setItemIcon(index,closeIcon);
        }
        ereaLabels.insert(label,erea);
    }
}





展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部