1.用继承pushbutton派生类来实现tab按钮,里面加一个QPushbutton关闭按钮;(自定义类:CCustomTabButton)
2.多个tab按钮用QHboxLayout做容器;
3.用QStackLayout做page容易,保存tab页的widget;
4.从QWidget继承类CCustomTabWidget组合tabbar和page
5.用qss渲染tarbar的效果;
#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-width: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-width:8px 8px 4px 4px;} " "#CCustomTabButton:checked {border-image: url(:/skin/skin/tab_btn_bg_checked.png) 8 8 2 4; border-width: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-width:30px;}
Demo下载地址:
http://download.csdn.net/detail/lanhy999/6386437