QT實現拖拽TabWidget選項卡形成單獨的視窗,雙擊標題欄可還原的功能【dock功能】
阿新 • • 發佈:2019-02-12
近期做QT,我也是新手,這個主要是用重構父類事件實現的,即子類化。
此文章是在http://blog.csdn.net/zmm19861210/article/details/9036779上看到的,但是我做了一定的修改[備註:下方的程式碼上未體現,還是老程式碼],我做了解構函式的修改,就是將堆上那些new出來的私有變數給delete掉,由於程式碼是在主機上除錯的,公司使用遠端桌面方式上網,所以沒有許可權上傳到遠端桌面來整個demo真是遺憾。
這個功能看似簡單,實現起來確實有點兒難度。 在程式碼裡詳細說明吧。 //CTabWidget.h #ifndef CTABWIDGET_H #define CTABWIDGET_H #include <QTabWidget> #include <QtGui> #include "CTabBar.h" class CTabWidget :public QTabWidget { Q_OBJECT public: CTabWidget(QWidget* =0); virtual ~CTabWidget(){}; public: CTabBar *tabBar; }; #endif // CTABWIDGET_H //CTabWidget.cpp #include "CTabWidget.h" CTabWidget::CTabWidget(QWidget *parent):QTabWidget(parent) { tabBar = new CTabBar; setTabBar(tabBar); //這裡是關鍵,這樣用我們自定義的CTabBar替換原來的QTabBar } //CTabBar.h #ifndef CTABBAR_H #define CTABBAR_H #include <QTabBar> #include <QtGui> class CTabBar :public QTabBar { Q_OBJECT public: CTabBar(QWidget* =0); virtual ~CTabBar(){}; protected: void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); //通過兩個事件模擬出tab被拖動的動作 private: bool pressFlag; signals: void sig_tabDrag(int,QPoint); }; #endif //CTabBar.cpp #include "CTabBar.h" #include <QtGui> CTabBar::CTabBar(QWidget *parent):QTabBar(parent),pressFlag(false) { } void CTabBar::mousePressEvent(QMouseEvent *event) { if (event->button()==Qt::LeftButton) { pressFlag = true; } QTabBar::mousePressEvent(event); } void CTabBar::mouseReleaseEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton &&pressFlag ) { pressFlag = false; if(tabRect(currentIndex()).contains( event->pos())) return; emit sig_tabDrag(currentIndex(),event->pos()); } } 現在實現視窗標題欄被雙擊動作 //CWidget.h #ifndef CWIDGET_H #define CWIDGET_H #include <QtGui/QWidget> class CWidget:public QWidget { Q_OBJECT public: CWidget(QWidget* = 0); ~CWidget(); protected: bool event(QEvent *); signals: void sig_doubleClickedTitleBar(); //被雙擊時發射的訊號 }; #endif //CWidget.cpp #include "CWidget.h" #include <QtGui> CWidget::CWidget(QWidget *parent):QWidget(parent) { } CWidget::~CWidget() { } bool CWidget::event(QEvent *event) { #ifdef unix if(event->type() == QEvent::MouseButtonDblClick){ //標題欄單擊沒反應,就單擊視窗邊緣替代吧 emit sig_doubleClickedTitleBar(); return true; } #endif if (event->type() == QEvent::NonClientAreaMouseButtonDblClick) //這個事件在Linux下沒有觸發,應該算是Qt的一個Bug吧 { emit sig_doubleClickedTitleBar(); return true; } return QWidget::event(event); } //CMainWindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTextEdit> #include "CTabWidget.h" #include "CTabBar.h" class CMainWindow:public QMainWindow { Q_OBJECT public: CMainWindow(QWidget* = 0); private: CTabWidget *tabWidget; private slots: void slot_tabBarDoubleClicked(); //響應雙擊彈回的槽函式 void slot_tabDrag(int index,QPoint point); //響應拖動動作的槽函式 void slot_closeTab(int); //關閉tab的槽函式 }; #endif // MAINWINDOW_H //CMainWindow.cpp #include "CMainWindow.h" #include "CTabWidget.h" #include "CWidget.h" #include <QtGui> CMainWindow::CMainWindow(QWidget *parent):QMainWindow(parent) { tabWidget = new CTabWidget(this); tabWidget->setMovable(true); tabWidget->setTabsClosable(true); tabWidget->setTabShape(QTabWidget::Triangular); //新增4個tab頁 tabWidget->addTab(new QTextEdit,"eidt 1"); tabWidget->addTab(new QTextEdit,"eidt 2"); tabWidget->addTab(new QTextEdit,"eidt 3"); tabWidget->addTab(new QTextEdit,"eidt 4"); setCentralWidget(tabWidget); connect(tabWidget->tabBar,SIGNAL(sig_tabDrag(int,QPoint)),this,SLOT(slot_tabDrag(int,QPoint))); connect(tabWidget,SIGNAL(tabCloseRequested(int)),this,SLOT(slot_closeTab(int))); connect(tabWidget,SIGNAL(currentChanged(int)),tabWidget,SLOT(setCurrentIndex(int))); resize(800,600); } void CMainWindow::slot_tabDrag(int index,QPoint point) { CWidget *widget = new CWidget; QWidget *draged = tabWidget->widget(index); QString windowName = tabWidget->tabText(index); tabWidget->removeTab(index); connect(widget,SIGNAL(sig_doubleClickedTitleBar()),this,SLOT(slot_tabBarDoubleClicked())); QGridLayout *layout = new QGridLayout; layout->addWidget(draged); widget->setLayout(layout); widget->resize(600,400); widget->move(point+pos()+tabWidget->pos()); widget->setWindowTitle(windowName); widget->show(); draged->show(); } void CMainWindow::slot_tabBarDoubleClicked() { CWidget *widget = qobject_cast<CWidget*>(sender()); QObjectList list = widget->children(); QTextEdit *edit = NULL; for(int i = 0;i<list.count();++i) { if(list[i]->inherits("QTextEdit")) { edit = qobject_cast<QTextEdit*>(list[i]); break; } } if(edit == NULL) { return ; } edit->setParent(tabWidget); tabWidget->addTab(edit,widget->windowTitle()); delete widget; } void CMainWindow::slot_closeTab(int index) { QWidget *draged = tabWidget->widget(index); tabWidget->removeTab(index); delete draged; } //main.cpp #include "CMainWindow.h" #include <QApplication> #include <QCleanlooksStyle> int main(int argc,char **argv) { QApplication app(argc,argv); QApplication::setStyle(new QCleanlooksStyle); QTextCodec::setCodecForTr(QTextCodec::codecForName("gb2312")); CMainWindow mainwindow; mainwindow.show(); return app.exec(); }