这个功能看似简单,实现起来确实有点儿难度。
在代码里详细说明吧。
//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();
}
Qt实现窗口tabwidget的拖出双击弹回功能
最新推荐文章于 2024-07-14 16:01:05 发布