QTabWidget 实现类似QQ聊天窗口(拖动分离出新的窗口)

        新版本的QQ聊天窗口可以实现拖动,分离出新的窗口。浏览器等软件也可以实现类似操作。所以心血来潮想用Qt实现类似的功能。想用QTabWidget直接实现是很难的,仔细阅读源码,发现QTabWidget内部是由QStackedWidget和QTabBar组合实现的。所以很自然的想到,只要继承QTabBar的子类重新实现QTabBar的

[cpp] view plain copy
 
  1. void mousePressEvent (QMouseEvent *e);  
  2. void mouseMoveEvent (QMouseEvent *e);  
  3. void mouseReleaseEvent (QMouseEvent *e);  

这三个方法,再把子定义的TabBar设置给QTabWidget就差不多了。但是还有个问题,QTabWidget的 setTabBar方法是protected的,所以只好再自定义一个QTabWidget的子类,在子类里调用setTabBar了。以下是我的简单实现:

 

[cpp] view plain copy
 
  1. class myTabBar:public QTabBar  
  2. {  
  3.     Q_OBJECT  
  4. public:  
  5.     myTabBar(QWidget *parent = NULL);  
  6.     ~myTabBar();  
  7. protected:  
  8.     void mousePressEvent (QMouseEvent *e);  
  9.     void mouseMoveEvent (QMouseEvent *e);  
  10.     void mouseReleaseEvent (QMouseEvent *e);  
  11.   
  12.  signals:  
  13.     void starDragTab(int index);  
  14.     void endDragTab();  
  15. private:  
  16.     void drag();  
  17.   
  18.     bool      m_isDrag;  
  19.     QPoint    m_mousePressPoint;  
  20.     QPoint    m_mouseReleasePoint;  
  21.       
  22. };  

 

[cpp] view plain copy
 
  1. void myTabBar::mouseMoveEvent(QMouseEvent *e)  
  2. {  
  3.     int index = this->currentIndex();  
  4.       
  5.     if (m_isDrag)  
  6.     {  
  7.         QPoint Point = e->pos();  
[cpp] view plain copy
 
  1.                 //拖动的垂直距离大于Bar的高度的话就新建一个窗口,这个应该比较好理解啊  
  2.         if (qAbs(m_mousePressPoint.y() - Point.y()) > this->height())  
  3.         {  
  4.             emit starDragTab(index);  
  5.         }  
  6.     }  
  7.     QTabBar::mouseMoveEvent(e);  
  8. }  
  9.   
  10. void myTabBar::mousePressEvent(QMouseEvent *e)  
  11. {  
  12.     if (e->button() == Qt::LeftButton)  
  13.     {  
  14.         m_isDrag = true;  
  15.         m_mousePressPoint = e->pos();  
  16.     }  
  17.     QTabBar::mousePressEvent(e);  
  18. }  
  19.   
  20. void myTabBar::mouseReleaseEvent(QMouseEvent *e)  
  21. {  
  22.     if (e->button() == Qt::LeftButton)  
  23.     {  
  24.         m_mouseReleasePoint = e->pos();  
  25.         if (qAbs(m_mousePressPoint.y() - m_mouseReleasePoint.y()) > this->height())  
  26.         {  
  27.             emit endDragTab();  
  28.         }  
  29.     }  
  30.     QTabBar::mouseReleaseEvent(e);  
  31. }  

 

[cpp] view plain copy
 
  1. class myTabWidget:public QTabWidget  
  2. {  
  3.     Q_OBJECT  
  4.   
  5. public:  
  6.     myTabWidget(QWidget *parent = NULL);  
  7.   
  8.     ~myTabWidget();  
  9.   
  10.   
  11. private slots:  
  12.     void starDrag(int index);  
  13.     void endDrag();  
  14.       
  15. private:  
  16.     myTabBar      *m_pTabBar;  
  17.     QString        m_dragTabLabel;  
  18.     QWidget       *m_pDragWidget;  
  19.     int            m_dragIndex;  
  20.       
  21.       
  22. };  

 

[cpp] view plain copy
 
  1. myTabWidget::myTabWidget(QWidget *parent/* = NULL*/):QTabWidget(parent)  
  2. {  
  3.     this->setAcceptDrops(true);  
  4.     setMouseTracking(true);  
  5.     m_pTabBar = new myTabBar(this);  
  6.     m_pTabBar->setMovable(true);  
  7.     setTabBar(m_pTabBar);               //设置自定义的Bar给TabWidget  
  8.     m_pDragWidget = NULL;  
  9.     connect(m_pTabBar,SIGNAL(starDragTab(int)),this,SLOT(starDrag(int)));  
  10.     connect(m_pTabBar,SIGNAL(endDragTab()),this,SLOT(endDrag()));  
  11. }  
  12.   
  13. void myTabWidget::starDrag(int index)  
  14. {  
  15.     m_dragTabLabel = this->tabText(index);  
  16.     m_pDragWidget  = this->widget(index);  
  17.     m_dragIndex    = index;  
  18.     QPixmap pix;  
  19.     //pix = QPixmap::grabWidget(m_pDragWidget);  
  20.     pix = QPixmap::grabWindow(this->winId());  
  21.     if (pix.isNull())  
  22.     {  
  23.         int i;  
  24.     }  
  25.     QMimeData *mimeData = new QMimeData;  
  26.     //mimeData->setText("drag tab");  
  27.     QDrag *drag = new QDrag(this);  
  28.     drag->setMimeData(mimeData);  
  29.     drag->setPixmap(pix.scaled(QSize(200,200)));    //这里主要是想想QQ一样,可以拖动的过程显示被拖动窗口的图片。但是效果还不是很好  
  30.     drag->exec();  
  31. }  
  32.   
  33. void myTabWidget::endDrag()  
  34. {  
  35.     myTabWidget *pWidget = new myTabWidget(NULL);  
  36.     if (m_pDragWidget)  
  37.     {  
[cpp] view plain copy
 
    1.                 //新建一个独立的窗口  
    2.     removeTab(m_dragIndex);  
    3.     pWidget->addTab(m_pDragWidget,m_dragTabLabel);  
    4.     pWidget->show();  
    5. }  

http://blog.csdn.net/hai200501019/article/details/8987379

posted @ 2016-02-01 18:17  findumars  Views(4710)  Comments(0Edit  收藏  举报