zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    cassandra安装
    002 spring boot框架,引入mybatis-generator插件,自动生成Mapper和Entity
    033 SSM综合练习09--数据后台管理系统--基于AOP的日志处理
    032 SSM综合练习08--数据后台管理系统--jsp页面显示当前用户名
    031 SSM综合练习07--数据后台管理系统--用户详情查询
    030 SSM综合练习06--数据后台管理系统--SSM权限操作及Spring Security入门
    029 SSM综合练习05--数据后台管理系统--订单分页查询
    027 SSM综合练习03--数据后台管理系统--product-list.jsp和main.jsp页面制作
    Idea 目录结构下有红色波浪线
    virtualbox上,android x86 的分辨率的设置
  • 原文地址:https://www.cnblogs.com/findumars/p/5175984.html
Copyright © 2011-2022 走看看