新版本的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. signals:
  12. void starDragTab(int index);
  13. void endDragTab();
  14. private:
  15. void drag();
  16. bool      m_isDrag;
  17. QPoint    m_mousePressPoint;
  18. QPoint    m_mouseReleasePoint;
  19. };
  1. void myTabBar::mouseMoveEvent(QMouseEvent *e)
  2. {
  3. int index = this->currentIndex();
  4. if (m_isDrag)
  5. {
  6. 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. void myTabBar::mousePressEvent(QMouseEvent *e)
  10. {
  11. if (e->button() == Qt::LeftButton)
  12. {
  13. m_isDrag = true;
  14. m_mousePressPoint = e->pos();
  15. }
  16. QTabBar::mousePressEvent(e);
  17. }
  18. void myTabBar::mouseReleaseEvent(QMouseEvent *e)
  19. {
  20. if (e->button() == Qt::LeftButton)
  21. {
  22. m_mouseReleasePoint = e->pos();
  23. if (qAbs(m_mousePressPoint.y() - m_mouseReleasePoint.y()) > this->height())
  24. {
  25. emit endDragTab();
  26. }
  27. }
  28. QTabBar::mouseReleaseEvent(e);
  29. }
  1. class myTabWidget:public QTabWidget
  2. {
  3. Q_OBJECT
  4. public:
  5. myTabWidget(QWidget *parent = NULL);
  6. ~myTabWidget();
  7. private slots:
  8. void starDrag(int index);
  9. void endDrag();
  10. private:
  11. myTabBar      *m_pTabBar;
  12. QString        m_dragTabLabel;
  13. QWidget       *m_pDragWidget;
  14. int            m_dragIndex;
  15. };
  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. void myTabWidget::starDrag(int index)
  13. {
  14. m_dragTabLabel = this->tabText(index);
  15. m_pDragWidget  = this->widget(index);
  16. m_dragIndex    = index;
  17. QPixmap pix;
  18. //pix = QPixmap::grabWidget(m_pDragWidget);
  19. pix = QPixmap::grabWindow(this->winId());
  20. if (pix.isNull())
  21. {
  22. int i;
  23. }
  24. QMimeData *mimeData = new QMimeData;
  25. //mimeData->setText("drag tab");
  26. QDrag *drag = new QDrag(this);
  27. drag->setMimeData(mimeData);
  28. drag->setPixmap(pix.scaled(QSize(200,200)));    //这里主要是想想QQ一样,可以拖动的过程显示被拖动窗口的图片。但是效果还不是很好
  29. drag->exec();
  30. }
  31. void myTabWidget::endDrag()
  32. {
  33. myTabWidget *pWidget = new myTabWidget(NULL);
  34. if (m_pDragWidget)
  35. {
    1. //新建一个独立的窗口
    2. removeTab(m_dragIndex);
    3. pWidget->addTab(m_pDragWidget,m_dragTabLabel);
    4. pWidget->show();
    5. }

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

QTabWidget 实现类似QQ聊天窗口(拖动分离出新的窗口)的更多相关文章

  1. [C# 网络编程系列]专题九:实现类似QQ的即时通信程序

    转自:http://www.cnblogs.com/zhili/archive/2012/09/23/2666987.html 引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例 ...

  2. WinForm实现类似QQ停靠,显示隐藏过程添加特效效果

    原文:WinForm实现类似QQ停靠,显示隐藏过程添加特效效果 这可能是个老题长谈的问题了,只是在项目中会用到这个效果,所以今天做个记录.大家见了别喷我.在项目中的需求是这样的. 打开程序,在屏幕的右 ...

  3. .net winForm 实现类似qq 弹出新闻

    .net winForm 实现类似qq 弹出新闻   一.背景: echong 之前一直用 公司大牛c语言写的一个弹出托管,前几天写东西的时候发现com调用不是那么好使.而手头上写的这个东西又是.ne ...

  4. 用C#代码实现类似QQ窗体的“上、左、右”停靠功能

    大家都知道QQ有一个自动停靠功能,即“上.左.右”,当你把窗体拖到屏幕边缘,然后移开鼠标它会自动缩放,然后只显示一小小点出来,我们仔细观察会发现其实它只露3像素左右的边缘,当你鼠标移上去它又会伸出来, ...

  5. 详解C# 网络编程系列:实现类似QQ的即时通信程序

    https://www.jb51.net/article/101289.htm 引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例来让大家更好的理解它们的工作原理以及怎样.Net ...

  6. 转:【专题九】实现类似QQ的即时通信程序

    引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例来让大家更好的理解它们的工作原理以及怎样.Net类库去实现它们的.为了让大家更好的理解我们平常中常见的软件QQ的工作原理,所以在 ...

  7. QQ聊天窗口上的广告与QQ弹窗广告的完美屏蔽去除

    涉及的软件 1. QQ  (笔者的为v8.2版本) 2. Win7 3. ADSafe(3.13.308.9900正式版) 前言 QQ广告十分讨人厌,除了QQ弹窗的广告,让人十分反感外,最近发现QQ聊 ...

  8. 专题九:实现类似QQ的即时通信程序

    引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例来让大家更好的理解它们的工作原理以及怎样.Net类库去实现它们的.为了让大家更好的理解我们平常中常见的软件QQ的工作原理,所以在 ...

  9. 使用plupload做一个类似qq邮箱附件上传的效果

    公司项目中使用的框架是springmvc+hibernate+spring,目前需要做一个类似qq邮箱附件上传的功能,暂时只是上传小类型的附件 处理过程和解决方案都需要添加附件,处理过程和解决方案都可 ...

随机推荐

  1. 概率图模型(PGM)学习笔记(四)-贝叶斯网络-伯努利贝叶斯-多项式贝叶斯

    之前忘记强调了一个重要差别:条件概率链式法则和贝叶斯网络链式法则的差别 条件概率链式法则 贝叶斯网络链式法则,如图1 图1 乍一看非常easy认为贝叶斯网络链式法则不就是大家曾经学的链式法则么,事实上 ...

  2. HTML5 Web Storage使用实例

    很久没写文章了,忙加懒实在没办法,之前也看过关于Web Storage的文章,当时就觉得各各浏览器的支持跟上来还早着呢,像我们这样做门户网站的一时半会儿也用不上,毕竟用户群体鱼目混杂嘛,最近各各浏览器 ...

  3. iOS 滤镜 转载,原文见正文首行链接

    转载自:http://blog.sina.com.cn/s/blog_5fb39f9101018gv7.html 直接上代码了: // // ViewController.m // 图片模糊处理 // ...

  4. C# 读取Excel日期格式

    读取Excel日期数据,一种方式是在EXCEL中把你的日期列的格式设置一下,设成"文本"型. 如果单元格格式设置为date,则在后台读出的数值是一个数值,如2008-08-08读出 ...

  5. java volatile关键字的理解

    转载:http://shmilyaw-hotmail-com.iteye.com/blog/1672779 一个多线程的示例引发的问题 在讨论这个关键字之前先看一个多线程的示例代码: public c ...

  6. BZOJ 1864: [Zjoi2006]三色二叉树( 树形dp )

    难得的ZJOI水题...DFS一遍就行了... ----------------------------------------------------------------------- #inc ...

  7. Nginx日志增长过快详细分析

    前言: Nginx日志里面Mobileweb_access.log增长特别大,一天上百兆,将近100W的访问记录,按照我们目前的规模,热点用户才500个左右,就算人人用手机app访问,怎么可能会有这么 ...

  8. 戴尔CEO:我们将专注于企业 而非手机业务

    9月13日消息,据国外媒体报道,戴尔公司董事长兼首席执行官迈克尔·戴尔(Michael Dell)周五接受了CNBC采访,谈了他对戴尔未来的打算.此前一天,迈克尔·戴尔提出的以250亿美元将戴尔私有化 ...

  9. jsp验证表单后再提交

    在提交表单时,我们常常需要验证核实表单内容,若都不为空时,方能提交:若有文本框为空则不提交,并获取鼠标焦点到文本框上 ,所以我们可以利用onsubmit的方法来做,请看下面例子: <html&g ...

  10. 一个人的旅行(Dijkstra算法)

    这道题可用Dijkstra算法,好像还有floyd等算法,慢慢研究 Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途 ...