New version of the QQ Chat window can be implemented to drag, separate a new window. Browsers and other software can also achieve similar operations. So a whim wanted to use QT to achieve similar functions. Want to use Qtabwidget direct realization is very difficult, carefully read the source code, found that Qtabwidget internal is composed of Qstackedwidget and qtabbar combination of implementation. So it's natural to think that as long as the subclass inheriting the Qtabbar is re-implementing Qtabbar's
[CPP]View PlainCopy
- void Mousepressevent (Qmouseevent *e);
- void Mousemoveevent (Qmouseevent *e);
- void Mousereleaseevent (Qmouseevent *e);
These three methods, and then the definition of the Tabbar set to Qtabwidget is almost. However, there is a problem, Qtabwidget Settabbar method is protected, so we have to customize a qtabwidget subclass, in the subclass called Settabbar. Here's my simple implementation:
[CPP]View PlainCopy
- Class Mytabbar: PublicQtabbar
- {
- 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;
- };
[CPP]View PlainCopy
- void Mytabbar::mousemoveevent (Qmouseevent *e)
- {
- int index = this->currentindex ();
- if (M_isdrag)
- {
- Qpoint point = E->pos ();
[CPP]View PlainCopy
- //Drag the vertical distance greater than bar height, then create a new window, this should be better understood AH
- 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);
- }
[CPP]View PlainCopy
- Class Mytabwidget: Publicqtabwidget
- {
- 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;
- };
[CPP]View PlainCopy
- Mytabwidget::mytabwidget (qwidget *parent/* = null*/): Qtabwidget (parent)
- {
- This->setacceptdrops (true);
- Setmousetracking (true);
- M_ptabbar = New Mytabbar (this);
- M_ptabbar->setmovable (true);
- Settabbar (M_ptabbar); //Set the custom bar to 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))); //Here is mainly to think about QQ, you can drag the process to display the picture is dragged window. But the effect is not very good.
- Drag->exec ();
- }
- void Mytabwidget::enddrag ()
- {
- Mytabwidget *pwidget = new Mytabwidget (NULL);
- if (m_pdragwidget)
- {
[CPP]View PlainCopy
- //Create a separate window
- RemoveTab (M_dragindex);
- Pwidget->addtab (M_pdragwidget,m_dragtablabel);
- Pwidget->show ();
- }
http://blog.csdn.net/hai200501019/article/details/8987379
Qtabwidget Implement similar QQ chat window (drag to detach a new window)