用Qt做ARM,發現Qt4中QTabWidget原生的關閉按鍵(X)太小,用觸摸板很難按到。於是乎想到類似於浏覽器的雙擊關閉功能,因為之前做過C#的資源管理器,以為可以直接綁定DoubleClick,可後來翻遍了也沒找到相應的SLOT,結果在QWidget中捕捉信號,就是沒有QTabWidget標簽的鼠標事件,坑爹那!隨後,又在網上各種搜索,結果找到的是各種問題,每一個准確回答出來的.....最後思來想去,實在不行,就用最笨的方法,仿Hock實現!
於是乎,我重載了QTabWidget(由於tabBar()是protected,坑爹啊!),這樣就可以獲取到標簽了。
1 class Tab : public QTabWidget 2 { 3 Q_OBJECT 4 public: 5 Tab(QWidget *parent = 0); 6 QTabBar* GetBar(); 7 protected: 8 void mousePressEvent(QMouseEvent *event); 9 };
然後在實現一個事件過濾器,首先判斷事件是雙擊事件,然後判斷是否為標簽位置,如果是則刪除當前標簽頁,由於雙擊事件中必觸發單擊,即標簽頁選中事件,因此無需考慮雙擊其他標簽頁引起的index變更問題。
1 #ifndef MYEVENTFILTER_H 2 #define MYEVENTFILTER_H 3 #include <QMainWindow> 4 #include <QMouseEvent> 5 #include "tab.h" 6 7 extern int tabindex_current; 8 extern int tabindex_old; 9 extern Tab *tabWidget; 10 extern QPoint tableft; 11 extern int tabwidth; 12 extern int tabheight; 13 14 //實現雙擊關閉Tab標簽 15 class myEventFilter: public QObject 16 { 17 public: 18 myEventFilter():QObject() 19 {}; 20 ~myEventFilter(){}; 21 22 bool eventFilter(QObject* object,QEvent* event) 23 { 24 if (event->type()==QEvent::MouseButtonDblClick) 25 { 26 QMouseEvent *e = static_cast<QMouseEvent*>(event); 27 QPoint pos = e->pos(); 28 int x1 = tableft.x(); 29 int x2 = tableft.x()+tabwidth; 30 int y1 = tableft.y(); 31 int y2 = tableft.y()+tabheight; 32 if (pos.x() >= x1 && pos.y() >= y1 && pos.x() <= x2 && pos.y() <= y2) 33 tabWidget->removeTab(tabindex_current); 34 } 35 return QObject::eventFilter(object,event); 36 }; 37 }; 38 39 #endif // MYEVENTFILTER_H
最後綁定到主函數main中,這樣就可捕捉到所有的事件了:
1 qApp->installEventFilter(new myEventFilter());
另外,需在標簽頁切換時更新寬度信息(高度無需更新):
1 void MainWindow::updateBar() 2 { 3 tabindex_current = tabWidget->currentIndex(); 4 tabindex_old = tabindex_current; 5 QTabBar *bar = tabWidget->GetBar(); 6 if (bar->size().width() > 0) 7 tabwidth = bar->size().width(); 8 }