新版本的QQ聊天窗口可以實現拖動,分離出新的窗口。瀏覽器等軟件也可以實現類似操作。所以心血來潮想用Qt實現類似的功能。想用QTabWidget直接實現是很難的,仔細閱讀源碼,發現QTabWidget內部是由QStackedWidget和QTabBar組合實現的。所以很自然的想到,只要繼承QTabBar的子類重新實現QTabBar的
- void mousePressEvent (QMouseEvent *e);
- void mouseMoveEvent (QMouseEvent *e);
- void mouseReleaseEvent (QMouseEvent *e);
這三個方法,再把子定義的TabBar設置給QTabWidget就差不多了。但是還有個問題,QTabWidget的 setTabBar方法是protected的,所以只好再自定義一個QTabWidget的子類,在子類里調用setTabBar了。以下是我的簡單實現:
- class myTabBar:public QTabBar
- {
- Q_OBJECT
- public:
- myTabBar(QWidget *parent = NULL);
- ~myTabBar();
- protected:
- void mousePressEvent (QMouseEvent *e);
- void mouseMoveEvent (QMouseEvent *e);
- void mouseReleaseEvent (QMouseEvent *e);
- signals:
- void starDragTab(int index);
- void endDragTab();
- private:
- void drag();
- bool m_isDrag;
- QPoint m_mousePressPoint;
- QPoint m_mouseReleasePoint;
- };
- void myTabBar::mouseMoveEvent(QMouseEvent *e)
- {
- int index = this->currentIndex();
- if (m_isDrag)
- {
- QPoint Point = e->pos();
- //拖動的垂直距離大於Bar的高度的話就新建一個窗口,這個應該比較好理解啊
- if (qAbs(m_mousePressPoint.y() - Point.y()) > this->height())
- {
- emit starDragTab(index);
- }
- }
- QTabBar::mouseMoveEvent(e);
- }
- void myTabBar::mousePressEvent(QMouseEvent *e)
- {
- if (e->button() == Qt::LeftButton)
- {
- m_isDrag = true;
- m_mousePressPoint = e->pos();
- }
- QTabBar::mousePressEvent(e);
- }
- void myTabBar::mouseReleaseEvent(QMouseEvent *e)
- {
- if (e->button() == Qt::LeftButton)
- {
- m_mouseReleasePoint = e->pos();
- if (qAbs(m_mousePressPoint.y() - m_mouseReleasePoint.y()) > this->height())
- {
- emit endDragTab();
- }
- }
- QTabBar::mouseReleaseEvent(e);
- }
- class myTabWidget:public QTabWidget
- {
- Q_OBJECT
- public:
- myTabWidget(QWidget *parent = NULL);
- ~myTabWidget();
- private slots:
- void starDrag(int index);
- void endDrag();
- private:
- myTabBar *m_pTabBar;
- QString m_dragTabLabel;
- QWidget *m_pDragWidget;
- int m_dragIndex;
- };
- myTabWidget::myTabWidget(QWidget *parent/* = NULL*/):QTabWidget(parent)
- {
- this->setAcceptDrops(true);
- setMouseTracking(true);
- m_pTabBar = new myTabBar(this);
- m_pTabBar->setMovable(true);
- setTabBar(m_pTabBar); //設置自定義的Bar給TabWidget
- m_pDragWidget = NULL;
- connect(m_pTabBar,SIGNAL(starDragTab(int)),this,SLOT(starDrag(int)));
- connect(m_pTabBar,SIGNAL(endDragTab()),this,SLOT(endDrag()));
- }
- void myTabWidget::starDrag(int index)
- {
- m_dragTabLabel = this->tabText(index);
- m_pDragWidget = this->widget(index);
- m_dragIndex = index;
- QPixmap pix;
- //pix = QPixmap::grabWidget(m_pDragWidget);
- pix = QPixmap::grabWindow(this->winId());
- if (pix.isNull())
- {
- int i;
- }
- QMimeData *mimeData = new QMimeData;
- //mimeData->setText("drag tab");
- QDrag *drag = new QDrag(this);
- drag->setMimeData(mimeData);
- drag->setPixmap(pix.scaled(QSize(200,200))); //這里主要是想想QQ一樣,可以拖動的過程顯示被拖動窗口的圖片。但是效果還不是很好
- drag->exec();
- }
- void myTabWidget::endDrag()
- {
- myTabWidget *pWidget = new myTabWidget(NULL);
- if (m_pDragWidget)
- {
- //新建一個獨立的窗口
- removeTab(m_dragIndex);
- pWidget->addTab(m_pDragWidget,m_dragTabLabel);
- pWidget->show();
- }
http://blog.csdn.net/hai200501019/article/details/8987379