Qt QTabWidget拖拽tab到另一个QTabWidget

QWidget实现拖放,需要设置接受拖放,
setAcceptDrops(true);
并实现下面事件:
  void dragEnterEvent(QDragEnterEvent *event);
  void dragMoveEvent(QDragMoveEvent *event);
  void dropEvent(QDropEvent *event);
  void mousePressEvent(QMouseEvent *event);
  void mouseMoveEvent(QMouseEvent *event);
如果我们只需要QWidget接受放下,那么就不需要实现:
  void mousePressEvent(QMouseEvent *event);
  void mouseMoveEvent(QMouseEvent *event);
这两个事件主要是,当我们需要QWidget实现拖动时才需要的。


我是按照有个例子做的,但是他做的不太好,拖拽之后只是单独的窗口,直接上代码

.h

#ifndef CTABWIDGET_H

#define CTABWIDGET_H
#include <qtabbar.h>
#include <qtabwidget.h>
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;
};
class myTabWidget:public QTabWidget
{
    Q_OBJECT
public:
    myTabWidget(QWidget *parent = NULL);
    ~myTabWidget()
    {
    }
protected:
    void dragEnterEvent(QDragEnterEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dropEvent(QDropEvent *event);
private slots:
    void starDrag(int index);
    void endDrag();
private:
    myTabBar      *m_pTabBar;
    QString        m_dragTabLabel;
    QWidget       *m_pDragWidget;
    int            m_dragIndex;
};
#endif // CTABWIDGET_H


.cpp

#include "tabwidget.h"

#include <QMouseEvent>
#include <qevent.h>
#include <qdrag.h>
#include<QMimeData>
#include <QApplication>
#include <QObjectUserData>
#include <QDebug>
myTabBar::myTabBar(QWidget *parent):QTabBar(parent), m_isDrag(false)
{
}
myTabBar::~myTabBar()
{
}
void myTabBar::mouseMoveEvent(QMouseEvent *e)
{
        QTabBar::mouseMoveEvent(e);
    int index = this->currentIndex();
    //if (m_isDrag)
    {
        QPoint Point = e->pos();
        //拖动的垂直距离大于Bar的高度的话就新建一个窗口,这个应该比较好理解啊
        if(!tabRect(index).contains(Point))
        //if (qAbs(m_mousePressPoint.y() - Point.y()) > this->height())
        {
            m_isDrag = false;
            qDebug() << "mouse drag";
            emit starDragTab(index);
        }
        else
        {
                        qDebug() << "mouse not drag";
        }
    }
    //else
    {
                                qDebug() << "11111111111";
    }
    //QTabBar::mouseMoveEvent(e);
    this->repaint();
}
void myTabBar::mousePressEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton)
    {
        qDebug() << "mouse press";
        m_isDrag = true;
        m_mousePressPoint = e->pos();
        this->setFocus();
    }
    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())
        {
            QWidget *p = qApp->widgetAt(e->pos());
            emit endDragTab();
        }
    }
    QTabBar::mouseReleaseEvent(e);
}*/
myTabWidget::myTabWidget(QWidget *parent/* = NULL*/):QTabWidget(parent)
{
    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()));
    this->setAcceptDrops(true);
    //setMouseTracking(true);
}
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");
    mimeData->setUserData(0, (QObjectUserData *)m_pDragWidget);
    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();
    }
}
void myTabWidget::dragEnterEvent(QDragEnterEvent *event)
{
    event->acceptProposedAction();
    QTabWidget::dragEnterEvent(event);
}
void myTabWidget::dragMoveEvent(QDragMoveEvent *event)
{
    QTabWidget::dragMoveEvent(event);
}
void myTabWidget::dropEvent(QDropEvent *event)
{
    QWidget *p = (QWidget *)event->mimeData()->userData(0);
    QObject *pp = event->source();
    //((myTabWidget *)pp)->tabBar()->clearFocus();
    if(pp == (QObject *)this)
    {
       QTabWidget::dropEvent(event);
       return QTabWidget::dropEvent(event);
    }
    this->addTab(p, "nima");
  //  QTabWidget::dropEvent(event);
}


#ifndef MAINWINDOW_H

#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class myTabWidget;
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
protected:
    void dropEvent(QDropEvent *e) override;
private:
    Ui::MainWindow *ui;
    myTabWidget *m_pTabWidget;
};
#endif // MAINWINDOW_H


#include "mainwindow.h"

#include "ui_mainwindow.h"
#include "tabwidget.h"
#include <QTextEdit>
#include <QSplitter>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setAcceptDrops(true);
    QSplitter *p = new QSplitter(this);
    m_pTabWidget = new myTabWidget(this);
    //m_pTabWidget->setMovable(true);
    m_pTabWidget->setTabsClosable(true);
    m_pTabWidget->setTabShape(QTabWidget::Triangular);
    //添加4个tab页
    m_pTabWidget->addTab(new QTextEdit,"eidt 1");
    m_pTabWidget->addTab(new QTextEdit,"eidt 2");
    m_pTabWidget->addTab(new QTextEdit,"eidt 3");
    m_pTabWidget->addTab(new QTextEdit,"eidt 4");
    myTabWidget *m_pTabWidget1 = new myTabWidget(this);
    //m_pTabWidget1->setMovable(true);
    m_pTabWidget1->setTabsClosable(true);
    m_pTabWidget1->setTabShape(QTabWidget::Triangular);
    //添加4个tab页
    m_pTabWidget1->addTab(new QTextEdit,"eidt 1");
    m_pTabWidget1->addTab(new QTextEdit,"eidt 2");
    m_pTabWidget1->addTab(new QTextEdit,"eidt 3");
    m_pTabWidget1->addTab(new QTextEdit,"eidt 4");
    p->addWidget(m_pTabWidget);
    p->addWidget(m_pTabWidget1);
    setCentralWidget(p);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::dropEvent(QDropEvent *e)
{
}


main.cpp

#include "mainwindow.h"

#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}


源码下载地址:https://download.csdn.net/download/wojiuguowei/10440774

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: QTabWidget一个常用的Qt小部件,用于创建带有多个选项卡的用户界面。它允许用户在不同的选项卡之间切换,并在每个选项卡添加不同的小部件。在Qt,可以通过拖拽的方式创建和设置QTabWidget。 首先,我们需要创建一个新的QTabWidget对象。可以使用以下代码: ``` QTabWidget *tabWidget = new QTabWidget(this); ``` 然后,可以使用tabWidget的函数来设置选项卡的外观和行为。例如,可以使用`setTabShape()`函数来设置选项卡的形状,如圆形或矩形: ``` tabWidget->setTabShape(QTabWidget::Triangular); ``` 接下来,可以通过调用`addTab()`函数,将小部件添加到选项卡。下面的代码示例,我们向tabWidget添加了两个小部件: ``` QWidget *tab1 = new QWidget(); QWidget *tab2 = new QWidget(); tabWidget->addTab(tab1, tr("Tab 1")); tabWidget->addTab(tab2, tr("Tab 2")); ``` 在拖拽方面,如果你想要拖拽一个选项卡,可以使用`setMovable(true)`函数来启用选项卡的拖拽功能: ``` tabWidget->setMovable(true); ``` 这使得用户可以通过点击选项卡并拖动来改变选项卡的顺序。 除了以上提到的方法外,还有其他许多函数可以用于设置和自定义QTabWidget。例如,你可以使用`setTabText()`函数来设置选项卡的文本,使用`setCurrentIndex()`函数来设置当前显示的选项卡等等。 总之,使用QTabWidget可以轻松创建和设置一个具有拖拽功能的选项卡界面,方便用户在不同的选项卡之间进行切换和操作。 ### 回答2: QTabWidgetQt框架提供的一个功能强大的小部件,可以用于显示多个选项卡。如果要将QTabWidget拖拽出来,可以使用以下步骤: 1. 创建一个新的窗口或窗体(例如QWidget或QMainWindow)来容纳QTabWidget。 2. 在新窗口的设计界面QTabWidget拖放到窗口的合适位置。 3. 为QTabWidget添加选项卡,并在每个选项卡添加相关的内容,例如QWidget或其他小部件。 4. 设置QTabWidget的属性,例如选择模式、是否可关闭选项卡等。 5. 在新窗口的代码,初始化QTabWidget并设置其相关属性。 6. 使用布局管理器(例如QVBoxLayout或QHBoxLayout)来自动调整QTabWidget和其他控件的位置和大小。 7. 将新窗口显示出来,并使用show()或exec()等方法。 8. 现在,用户就可以通过拖动选项卡头部或点击选项卡头部来拖拽和选择相应的选项卡。 9. 根据需要,可以添加其他功能,例如右键菜单、拖放功能、样式表等来进一步丰富QTabWidget的外观和交互体验。 总之,使用QTabWidget可以轻松创建一个具有多个选项卡的窗口,并通过拖拽选项卡头部来切换和重新排列选项卡的位置,从而实现更灵活的用户界面设计。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金士顿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值