• qt -- QTabWidget 中支持拖拽TabBar项


    目录

    需求

    效果

    代码


    需求

    1、支持拖动交换TabBar标签位置
    ui->tabWidget->setMovable(true);

    2、支持将TabBar项拖出 QTabWidget 置顶显示

    3、支持将拖出的TabBar项重新拖入QTabWidget中

    效果

     

    代码

    MainWindow

    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include "custom_tabWidget/custom_tabwidget.h"
    4. MainWindow::MainWindow(QWidget *parent) :
    5. QMainWindow(parent),
    6. ui(new Ui::MainWindow)
    7. {
    8. ui->setupUi(this);
    9. m_pTabWidget = new CustomTabWidget(this);
    10. ui->verticalLayout->addWidget(m_pTabWidget);
    11. m_pTabWidget->addTab(new QTextEdit,"eidt 1");
    12. m_pTabWidget->addTab(new QTextEdit,"eidt 2");
    13. m_pTabWidget->addTab(new QTextEdit,"eidt 3");
    14. m_pTabWidget->addTab(new QTextEdit,"eidt 4");
    15. }
    16. MainWindow::~MainWindow()
    17. {
    18. delete ui;
    19. }
    20. /*************************************/
    21. #ifndef MAINWINDOW_H
    22. #define MAINWINDOW_H
    23. #include <QMainWindow>
    24. #include <QTextEdit>
    25. namespace Ui {
    26. class MainWindow;
    27. }
    28. class CustomTabWidget;
    29. class MainWindow : public QMainWindow
    30. {
    31. Q_OBJECT
    32. public:
    33. explicit MainWindow(QWidget *parent = 0);
    34. ~MainWindow();
    35. private:
    36. Ui::MainWindow *ui;
    37. CustomTabWidget* m_pTabWidget;
    38. };
    39. #endif // MAINWINDOW_H
    CustomTabBar
    1. #ifndef CUSTOM_TABBAR_H
    2. #define CUSTOM_TABBAR_H
    3. #include <QTabBar>
    4. #include <QObject>
    5. #include <QPoint>
    6. #include <QMouseEvent>
    7. class CustomTabBar : public QTabBar
    8. {
    9. Q_OBJECT
    10. public:
    11. CustomTabBar(QWidget *parent = nullptr);
    12. ~CustomTabBar();
    13. protected:
    14. void mousePressEvent(QMouseEvent *event);
    15. void mouseMoveEvent(QMouseEvent *event);
    16. void mouseReleaseEvent(QMouseEvent *event);
    17. signals:
    18. void signalStartDragTab(int);
    19. void signalStopDrapTab();
    20. private:
    21. bool m_bPressFlag;
    22. QPoint m_pointPress;
    23. QPoint m_pointRelease;
    24. };
    25. #endif // CUSTOM_TABBAR_H
    26. /******************************/
    27. #include "custom_tabbar.h"
    28. CustomTabBar::CustomTabBar(QWidget *parent):QTabBar(parent)
    29. {
    30. m_bPressFlag = false;
    31. setMovable(true);
    32. //this->setAcceptDrops(true);
    33. }
    34. CustomTabBar::~CustomTabBar()
    35. {
    36. }
    37. void CustomTabBar::mousePressEvent(QMouseEvent *event)
    38. {
    39. if(event->button() == Qt::LeftButton && currentIndex() >= 0)
    40. {
    41. m_bPressFlag = true;
    42. m_pointPress = event->pos();
    43. }
    44. QTabBar::mousePressEvent(event);
    45. }
    46. void CustomTabBar::mouseMoveEvent(QMouseEvent *event)
    47. {
    48. if(m_bPressFlag && event->buttons()) {
    49. if(qAbs(m_pointPress.y() - event->pos().y()) > this->height() &&
    50. !tabRect(this->currentIndex()).contains(event->pos())) {
    51. m_bPressFlag = false;
    52. if(this->count() != 1) {
    53. emit signalStartDragTab(this->currentIndex());
    54. emit signalStopDrapTab();
    55. }
    56. }
    57. }
    58. QTabBar::mouseMoveEvent(event);
    59. }
    60. void CustomTabBar::mouseReleaseEvent(QMouseEvent *event)
    61. {
    62. m_bPressFlag = false;
    63. m_pointRelease = event->pos();
    64. if (qAbs(m_pointPress.y() - m_pointRelease.y()) > this->height())
    65. {
    66. // if(this->count() != 1) {
    67. // emit signalStopDrapTab();
    68. // }
    69. }
    70. QTabBar::mouseMoveEvent(event);
    71. }
    CustomTabWidget
    1. #ifndef CUSTOM_TABWIDGET_H
    2. #define CUSTOM_TABWIDGET_H
    3. #include <QDrag>
    4. #include <QTabWidget>
    5. #include <QMimeData>
    6. #include <QDragEnterEvent>
    7. #include <QMouseEvent>
    8. class CustomTabBar;
    9. class CustomPopupPage;
    10. class CustomTabWidget : public QTabWidget
    11. {
    12. public:
    13. CustomTabWidget(QWidget *parent = nullptr);
    14. ~CustomTabWidget();
    15. private:
    16. void init();
    17. protected:
    18. // void dragEnterEvent(QDragEnterEvent *event);
    19. // void dragMoveEvent(QDragMoveEvent *event);
    20. // void dropEvent(QDropEvent *event);
    21. // void mousePressEvent(QMouseEvent *event);
    22. // void mouseMoveEvent(QMouseEvent *event);
    23. // void mouseReleaseEvent(QMouseEvent *event);
    24. private slots:
    25. void addTabPage(const QPoint &pos);
    26. private:
    27. CustomTabBar* m_pTabBar;
    28. QWidget* m_pDragTab; //拖拽显示的页面
    29. int m_nTabIndex; //标签索引
    30. QString m_strTitle; //标签标题
    31. CustomPopupPage* m_pPopupPage;
    32. };
    33. #endif // CUSTOM_TABWIDGET_H
    34. /*******************************/
    35. #include "custom_tabwidget.h"
    36. #include "custom_tabbar.h"
    37. #include "custom_popup_page.h"
    38. CustomTabWidget::CustomTabWidget(QWidget *parent):
    39. QTabWidget(parent),
    40. m_pTabBar(nullptr)
    41. {
    42. init();
    43. }
    44. CustomTabWidget::~CustomTabWidget()
    45. {
    46. }
    47. void CustomTabWidget::init()
    48. {
    49. this->setAcceptDrops(true);
    50. m_pTabBar = new CustomTabBar(this);
    51. this->setTabBar(m_pTabBar);
    52. //拖拽窗口
    53. connect(m_pTabBar, &CustomTabBar::signalStartDragTab, this, [&](int index) {
    54. m_nTabIndex = index;
    55. m_strTitle = this->tabText(index);
    56. m_pDragTab = this->widget(index);
    57. });
    58. //拖拽释放窗口显示
    59. connect(m_pTabBar, &CustomTabBar::signalStopDrapTab, this, [&]() {
    60. // this->removeTab(m_nTabIndex);
    61. m_pPopupPage = new CustomPopupPage(this);
    62. connect(m_pPopupPage, &CustomPopupPage::signalDragRelease, this, &CustomTabWidget::addTabPage);
    63. connect(m_pPopupPage, &CustomPopupPage::signalAddTab, this, [&](){
    64. const int index = this->insertTab(m_nTabIndex, m_pDragTab, m_strTitle);
    65. //切换为当前新增页
    66. this->setCurrentIndex(index);
    67. });
    68. m_pPopupPage->setContentWidget(m_pDragTab);
    69. m_pPopupPage->setWindowTitle(m_strTitle);
    70. m_pPopupPage->resize(m_pDragTab->size());
    71. m_pDragTab->show();
    72. m_pPopupPage->exec();
    73. });
    74. }
    75. void CustomTabWidget::addTabPage(const QPoint &pos)
    76. {
    77. const QPoint bar_pos = this->tabBar()->mapFromGlobal(pos);
    78. //如果又拖回了tabbar范围内,把widget取出来放回tab
    79. if(this->tabBar()->contentsRect().contains(bar_pos))
    80. {
    81. const int index = this->insertTab(m_nTabIndex, m_pPopupPage->getContentWidget(), m_pPopupPage->windowTitle());
    82. //切换为当前新增页
    83. this->setCurrentIndex(index);
    84. m_pPopupPage->disconnect();
    85. m_pPopupPage->close();
    86. }
    87. }
    CustomPopupPage
    1. #ifndef CUSTOM_POPUP_PAGE_H
    2. #define CUSTOM_POPUP_PAGE_H
    3. #include <QObject>
    4. #include <QWidget>
    5. #include <QDialog>
    6. #include <QEvent>
    7. #include <QMouseEvent>
    8. #include <QVBoxLayout>
    9. #include <QCloseEvent>
    10. class CustomPopupPage : public QDialog
    11. {
    12. Q_OBJECT
    13. public:
    14. CustomPopupPage(QWidget *parent = nullptr);
    15. ~CustomPopupPage();
    16. void setContentWidget(QWidget *page);
    17. QWidget* getContentWidget();
    18. protected:
    19. bool event(QEvent *event);
    20. void closeEvent(QCloseEvent *event);
    21. signals:
    22. void signalDragRelease(const QPoint &globalPos);
    23. void signalAddTab();
    24. private:
    25. QWidget * m_page;
    26. };
    27. #endif // CUSTOM_POPUP_PAGE_H
    28. /******************************************************/
    29. #include "custom_popup_page.h"
    30. CustomPopupPage::CustomPopupPage(QWidget *parent):
    31. QDialog(parent)
    32. {
    33. m_page = nullptr;
    34. }
    35. CustomPopupPage::~CustomPopupPage()
    36. {
    37. }
    38. void CustomPopupPage::setContentWidget(QWidget *page)
    39. {
    40. if(!page)
    41. return;
    42. m_page = page;
    43. QVBoxLayout *layout = new QVBoxLayout(this);
    44. layout->setMargin(0);
    45. layout->addWidget(page);
    46. }
    47. QWidget *CustomPopupPage::getContentWidget()
    48. {
    49. return m_page;
    50. }
    51. bool CustomPopupPage::event(QEvent *event)
    52. {
    53. switch(event->type())
    54. {
    55. case QEvent::MouseButtonRelease:
    56. case QEvent::NonClientAreaMouseButtonRelease:
    57. {
    58. QMouseEvent *e=static_cast<QMouseEvent*>(event);
    59. if(e && e->button()==Qt::LeftButton)
    60. {
    61. emit signalDragRelease(e->globalPos());
    62. }
    63. }
    64. break;
    65. }
    66. return QDialog::event(event);
    67. }
    68. void CustomPopupPage::closeEvent(QCloseEvent *event)
    69. {
    70. emit signalAddTab();
    71. }

  • 相关阅读:
    扫雷游戏(C语言)
    《TCP IP网络编程》尹圣雨----2.第一章习题
    【图像处理】基于matlab GUI图像处理【含Matlab源码 2123期】
    怎么在谷歌浏览器中安装.crx扩展名的离线chrome插件
    龙芯3A3000源码编译安装deepin-ide
    Sentinel流量控制
    JavaScript洗牌算法打乱数组元素顺序
    电影推荐 - 亲密
    利用WPS功能破解及本地恢复密码
    有哪些常用的前端构建工具?
  • 原文地址:https://blog.csdn.net/qq_41653875/article/details/125421443