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

发布于 2019-09-26 作者 风铃 74次 浏览 版块 前端

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

  1. void mousePressEvent (QMouseEvent *e);  
  2. void mouseMoveEvent (QMouseEvent *e);  
  3. void mouseReleaseEvent (QMouseEvent *e);  

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

 

  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. };  

  1. void myTabBar::mouseMoveEvent(QMouseEvent *e)  

  2. {  

  3.     int index = this->currentIndex();  

  4.       

  5.     if (m_isDrag)  

  6.     {  

  7.         QPoint Point = e->pos();  



  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. }  



  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. };  



  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.     {  



    1.                 //新建一个独立的窗口  

    2.     removeTab(m_dragIndex);  

    3.     pWidget->addTab(m_pDragWidget,m_dragTabLabel);  

    4.     pWidget->show();  

    5. }  


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

收藏
暂无回复