QT下自定义QQ聊天窗口tab控件


1.用继承pushbutton派生类来实现tab按钮,里面加一个QPushbutton关闭按钮;(自定义类:CCustomTabButton

2.多个tab按钮用QHboxLayout做容器;

3.用QStackLayout做page容易,保存tab页的widget;

4.从QWidget继承类CCustomTabWidget组合tabbar和page

5.用qss渲染tarbar的效果;

QT下自定义QQ聊天窗口tab控件

QT下自定义QQ聊天窗口tab控件

#ifndef CCUSTOMTABWIDGET_H
#define CCUSTOMTABWIDGET_H

#include <QPushButton>
#include <QList>

class QLabel;
class QStackedLayout;
class QHBoxLayout;

class CCustomTabButton :public QPushButton
{
    Q_OBJECT
public:
    explicit CCustomTabButton(QWidget *parent = 0);
    ~CCustomTabButton();

    void setText(QString text);
    void setIndex(int nIndex){
        m_nIndex = nIndex;
    }
    int getIndex(){
        return m_nIndex;
    }

signals:
    void clicked(int nIndex);
    void closeClicked(int nIndex);
protected:
    void resizeEvent(QResizeEvent * event);
    void mousePressEvent(QMouseEvent * event);
    void enterEvent(QEvent * event );
    void leaveEvent(QEvent * event );

private slots:
    void on_btnClose_clicked();
private:
    QPushButton * m_btnClose;
    int m_nIndex;
 };

class CCustomTabWidget : public QWidget
{
    Q_OBJECT
public:
    explicit CCustomTabWidget(QWidget *parent = 0);
    ~CCustomTabWidget();

    void AddTab(QString title, QWidget *widget);
    void RemoveTab(int index);
    void Clear();

    void SetCurrentWidget(QWidget *widget);
    void SetCurrentIndex(int index);
    int CurrentIndex();
    int count()
    {
        return m_listTabButton.count();
    }
    QWidget* widget(int nIndex);

protected:
    void paintEvent(QPaintEvent *);
signals:

private slots:
    void on_tabbar_closeClicked(int nIndex);
    void on_tabbar_clicked(int nIndex);

private:
    QList<CCustomTabButton *> m_listTabButton;
    QHBoxLayout *m_hlTabbar;
    QLabel *m_lblTabbar;
    QStackedLayout *m_stackWidget;
    int m_nCurrentIndex;
};

#endif // CCUSTOMTABWIDGET_H


#include "ccustomtabwidget.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QStackedLayout>
#include <QDebug>
#include <QStyleOption>
#include <QPainter>

CCustomTabButton::CCustomTabButton(QWidget *parent):
    QPushButton(parent)
{

    this->setCheckable(true);

    m_btnClose = new QPushButton(this);
    m_btnClose->setObjectName(QString::fromUtf8("CCustomTabCloseButton"));
    m_btnClose->setVisible(false);

    m_btnClose->setGeometry(QRect(this->width()-16,0,16,16));
    connect(m_btnClose, SIGNAL(clicked()), this, SLOT(on_btnClose_clicked()));
}

CCustomTabButton::~CCustomTabButton()
{
    delete m_btnClose;
}

void CCustomTabButton::resizeEvent(QResizeEvent * event)
{
    m_btnClose->setGeometry(QRect(this->width()-16,0,16,16));

}

void CCustomTabButton::mousePressEvent(QMouseEvent * event)
{
    emit clicked(m_nIndex);
}

void CCustomTabButton::enterEvent ( QEvent * event )
{
    QPushButton::enterEvent(event);

    m_btnClose->setVisible(true);
}

void CCustomTabButton::leaveEvent ( QEvent * event )
{
    QPushButton::leaveEvent(event);

    m_btnClose->setVisible(false);

}

void CCustomTabButton::on_btnClose_clicked()
{
    emit closeClicked(m_nIndex);
}

void CCustomTabButton::setText(QString text)
{
    QPushButton::setText(text);
    this->setToolTip(text);
}



/***
  CCustomTabWidget
**/
CCustomTabWidget::CCustomTabWidget(QWidget *parent) :
    QWidget(parent)
{
    QVBoxLayout *vlMain = new QVBoxLayout();
    vlMain->setSpacing(0);
    vlMain->setMargin(0);

    this->setLayout(vlMain);

    m_lblTabbar = new QLabel();
    m_lblTabbar->setObjectName(QString::fromUtf8("CCustomTabBar"));

    m_hlTabbar = new QHBoxLayout();
    m_hlTabbar->setSpacing(0);
    m_hlTabbar->setMargin(0);
    m_hlTabbar->setContentsMargins(5,0,5,0);
    m_hlTabbar->addStretch();
    m_lblTabbar->setLayout(m_hlTabbar);

    vlMain->addWidget(m_lblTabbar);

    m_stackWidget = new QStackedLayout();
    vlMain->addLayout(m_stackWidget);
}

CCustomTabWidget::~CCustomTabWidget()
{
    for (int i = 0; i < m_listTabButton.size(); i++)
    {
        delete m_listTabButton.at(i);
    }
    m_listTabButton.clear();

    for (int i = 0; i < m_stackWidget->count(); i++)
    {
        delete m_stackWidget->widget(i);
    }

    delete m_lblTabbar;
    delete m_stackWidget;

}

void CCustomTabWidget::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void CCustomTabWidget::on_tabbar_closeClicked(int nIndex)
{
    if (nIndex < 0 || nIndex >= m_listTabButton.size())
    {
        qDebug()<<"CCustomTabWidget::on_tabbar_closeClicked error!!!"<<nIndex;
        return;
    }

    this->RemoveTab(nIndex);
}

void CCustomTabWidget::on_tabbar_clicked(int nIndex)
{
    if (nIndex < 0 || nIndex >= m_listTabButton.size())
    {
        qDebug()<<"CCustomTabWidget::on_tabbar_clicked error!!!"<<nIndex;
        return;
    }

    this->SetCurrentIndex(nIndex);
}

QWidget* CCustomTabWidget::widget(int nIndex)
{
    if (nIndex < 0 || nIndex >= m_listTabButton.size())
    {
         return NULL;
    }

    return m_stackWidget->widget(nIndex);
}

void CCustomTabWidget::AddTab(QString title, QWidget *widget)
{
    CCustomTabButton *btn = new CCustomTabButton();
    btn->setObjectName(QString::fromUtf8("CCustomTabButton"));
    connect(btn, SIGNAL(clicked(int)), this, SLOT(on_tabbar_clicked(int)));
    connect(btn, SIGNAL(closeClicked(int)), this, SLOT(on_tabbar_closeClicked(int)));
    btn->setText(title);
    int nIndex = m_listTabButton.size();
    btn->setIndex(nIndex);

    m_hlTabbar->insertWidget(nIndex,btn);
    m_listTabButton.append(btn);

    m_stackWidget->addWidget(widget);


    this->SetCurrentIndex(nIndex);
}

void CCustomTabWidget::RemoveTab(int index)
{
    if (index < 0 || index >= m_listTabButton.size())
    {
        qDebug()<<"CCustomTabWidget::RemoveTab error!!!"<<index;
        return;
    }

    CCustomTabButton *btn = m_listTabButton.at(index);
    m_hlTabbar->removeWidget(btn);
    m_listTabButton.removeAt(index);
    delete btn;

    QWidget * widget = m_stackWidget->widget(index);
    m_stackWidget->removeWidget(widget);
    delete widget;

    if (m_listTabButton.size() > 0)
    {
        int nCurrIndex = index-1 >= 0?index-1 :0;

        this->SetCurrentIndex(nCurrIndex);
    }
}

void CCustomTabWidget::Clear()
{
    for (int i = 0; i < m_listTabButton.size(); i++)
    {
        m_hlTabbar->removeWidget(m_listTabButton.at(i));
        delete m_listTabButton.at(i);
    }
    m_listTabButton.clear();

    for (int i = 0; i < m_stackWidget->count(); i++)
    {
        QWidget *widget = m_stackWidget->widget(0);
        m_stackWidget->removeWidget(widget);
        delete widget;
    }

}

void CCustomTabWidget::SetCurrentWidget(QWidget *widget)
{
    if (widget == NULL)
    {
        return;
    }

    for (int i = 0; i < m_stackWidget->count(); i++)
    {
        if(m_stackWidget->widget(i) == widget)
        {
            this->SetCurrentIndex(i);
            break;
        }
    }

}

void CCustomTabWidget::SetCurrentIndex(int index)
{
    if (index < 0 || index >= m_listTabButton.size())
    {
        qDebug()<<"CCustomTabWidget::SetCurrentTab error!!!"<<index;
        return;
    }

    m_nCurrentIndex = index;
    if (m_listTabButton.size() == 1)
    {
        m_lblTabbar->setVisible(false);
    }
    else
    {
        m_lblTabbar->setVisible(true);
    }

    for (int i = 0; i < m_listTabButton.size(); i++)
    {
        m_listTabButton.at(i)->setIndex(i);
        m_listTabButton.at(i)->setVisible(true);

        if (i == m_nCurrentIndex)
        {
            m_listTabButton.at(i)->setChecked(true);
            qDebug()<<"checked:"<<i;
        }
        else
        {
            m_listTabButton.at(i)->setChecked(false);
        }
    }
    m_stackWidget->setCurrentIndex(m_nCurrentIndex);
}

int CCustomTabWidget::CurrentIndex()
{
    return m_nCurrentIndex;
}


#CCustomTabButton {max-height:30px; min-height:20px; border-image: url(:/skin/skin/tab_btn_bg_normal.png)  8 8 2 4; border-8px 8px 2px 4px;background-color: transparent;color:black;} "
            "#CCustomTabButton:hover {border-image: url(:/skin/skin/tab_btn_bg_hover.png) 8 8 4 4; border-8px 8px 4px 4px;} "
            "#CCustomTabButton:checked {border-image: url(:/skin/skin/tab_btn_bg_checked.png)  8 8 2 4; border-8px 8px 2px 4px;} "
            "#CCustomTabCloseButton{border-image: url(:/skin/skin/tab_btn_close_normal.png);}"
            "#CCustomTabCloseButton:hover{border-image: url(:/skin/skin/tab_btn_close_hover.png);}"
            "#CCustomTabBar{min-height:30px;background:transparent;border-bottom:1px solid #cacaca; } "
            "CCustomTabWidget{border-image: url(:/skin/skin/tab_bg1.png) 30; border-30px;}

Demo下载地址:

http://download.csdn.net/detail/lanhy999/6386437