无锡网站开发电话,3d自学网站,某高校门户网站开发案例,wordpress没有中文版往期回顾#xff1a; 【QT入门】 无边框窗口设计之实现窗口阴影-CSDN博客 【QT入门】 无边框窗口设计之实现圆角窗口-CSDN博客 【QT入门】 无边框窗口设计综合运用之自定义标题栏带圆角阴影的窗口-CSDN博客 【QT入门】 无边框窗口设计之综合运用#xff0c;实现WPS的tab页面 …往期回顾 【QT入门】 无边框窗口设计之实现窗口阴影-CSDN博客 【QT入门】 无边框窗口设计之实现圆角窗口-CSDN博客 【QT入门】 无边框窗口设计综合运用之自定义标题栏带圆角阴影的窗口-CSDN博客 【QT入门】 无边框窗口设计之综合运用实现WPS的tab页面
一、最终效果 实现自增tab页面不同tab页面之间的切换等同时右键单击tab页面会弹出菜单栏
二、主界面类设计
主界面类负责整合标题栏和下面的widget整合很简单创建一个tab类添加进来就ok
WPSDemo::WPSDemo(QWidget* parent): QWidget(parent)
{ui.setupUi(this);setWindowFlags(Qt::FramelessWindowHint);//设置为无边框窗口setStyleSheet(background-color:#E3E4E7);//设置背景颜色tabbrowser* pTab new tabbrowser(this); QHBoxLayout* pHLay new QHBoxLayout(this);pHLay-addWidget(pTab);pHLay-setContentsMargins(6, 6, 6, 6);setLayout(pHLay);connect(pTab, tabbrowser::sig_close, this, WPSDemo::on_close);
}
三、Tab类设计 tab类负责创建tab实现相关逻辑重点还是在这里。主要是创建、删除tab标签以及样式切换。还有就是单击右键显示菜单这几个点需要注意。
1、定义tab标签样式
首先定义了两个字符串变量 qss0 和 qss1分别存储了两种不同的 QSS 样式表用于设置标签页的外观。当tab标签的数量超过一定范围时会出现一个切换按钮也就需要切换不同样式。
QString qss0 QTabBar::tab{ \font: 75 12pt Arial; \text-align:left; \width:184px; \height:32; \background:#FFFFFF; \border:2px solid #FFFFFF; \border-bottom-color:#FFFFFF; \border-top-left-radius:4px; \border-top-right-radius:4px; \padding:2px; \margin-top:0px; \margin-right:1px; \margin-left:1px; \margin-bottom:0px;} \QTabBar::tab:selected{ \color:#333333; /*文字颜色*/ \background-color:#FFFFFF;} \QTabBar::tab:!selected{ \color:#B2B2B2; \border-color:#FFFFFF;} \QTabBar::scroller{width: 0px;};
QString qss1 QTabBar::tab{ \font: 75 12pt Arial; \text-align:left; \width:184px; \height:32; \background:#FFFFFF; \border:2px solid #FFFFFF; \border-bottom-color:#FFFFFF; \border-top-left-radius:4px; \border-top-right-radius:4px; \padding:2px; \margin-top:0px; \margin-right:1px; \margin-left:1px; \margin-bottom:0px;} \QTabBar::tab:selected{ \color:#333333; /*文字颜色*/ \background-color:#FFFFFF;} \QTabBar::tab:!selected{ \color:#B2B2B2; \border-color:#FFFFFF;} \QTabBar::scroller{width: 36px;};
2、初始化标签页并设置属性 在 tabbrowser 类的构造函数中初始化一个标签页并设置了一些标签页的属性如滚动、可关闭、可移动等。然后调用了initTabWidget()函数初始化标签页部件并设置了初始的标签页操作标志为 NORMAL。
tabbrowser::tabbrowser(QWidget* parent) :QTabWidget(parent)
{this-addTab(new QWidget, u8稻壳); //定义最开始的tabthis-setUsesScrollButtons(true); //滚动鼠标可切换tabthis-setTabsClosable(true); //显示tab右侧的关闭按钮this-setMovable(true); //tab可移动位置initTabWidget(); //初始化tabsetTabBarFlag(NORMAL); this-setStyleSheet(qss0);connect(this, QTabWidget::tabCloseRequested, this, tabbrowser::on_closeTab);
}
这里我们一共定义了4种标签页操作标志 //tab操作标志enum TAB_FLAG{NEW, //新建标签页的操作标志CLOSE, //关闭标签页的操作标志NORMAL, //普通标签页的操作标志SPECIAL //特殊标签页的操作标志比如当只剩下一个标签页时};
然后需要根据传入的标志值计算标签页的总宽度并根据总宽度是否超过当前窗口宽度来切换不同的 QSS 样式表。
3、创建和删除tab标签
1、创建tab标签
用一个 on_newTab() 函数来新建标签页获取当前标签页数量并转换为字符串作为标题然后添加新的标签页并根据需要设置标签页为可关闭状态。
void tabbrowser::on_newTab()
{int nCount count(); //获取当前标签页的数量。QString title QString::number(nCount); //将当前标签页数量转换为字符串。title Page title; //将标题设置为 Page 后接当前标签页数量的字符串// 这里写的有问题应该是 insertTabthis-addTab(new QWidget, title); //检查标签页是否可关闭如果不可关闭则设置标签页为可关闭状态。if (!tabsClosable()){setTabsClosable(true);}setTabBarFlag(NEW);
}
2、删除tab标签 用一个on_closeTab() 函数来关闭指定索引的标签页删除对应的窗口部件并根据剩余标签页数量设置标签栏的标志当只剩下一个标签页时将标签页设置为不可关闭状态。
//关闭指定索引的标签页并根据情况设置标签栏的标志
void tabbrowser::on_closeTab(int index)
{//删除指定索引的标签页的对应窗口部件widget(index)-deleteLater();setTabBarFlag(CLOSE); //设置标签栏的标志为 CLOSE//当只剩下1个tab时if (count() 1){setTabsClosable(false); //设置标签页为不可关闭状态setTabBarFlag(SPECIAL); //设置标签栏的标志为 SPECIAL}
}
参考一下删除一个tab是怎么做的是根据鼠标点击获取的index来delete基于删除一个tab标签的操作那么删除整个标签栏的操作自然也就很简单。我直接for循环delete所有只剩下初始的那一个即可。
void tabbrowser::on_closeAllTab()
{for (int i count(); i 0; i--){//删除指定索引的标签页的对应窗口部件widget(i)-deleteLater();setTabBarFlag(CLOSE); //设置标签栏的标志为 CLOSE//当只剩下1个tab时if (count() 1){setTabsClosable(false); //设置标签页为不可关闭状态setTabBarFlag(SPECIAL); //设置标签栏的标志为 SPECIAL}}
}
4、单击右键显示菜单
由于都是只创建菜单大部分的具体实现都没做所以还是很简单的
//右键单击tab出现菜单栏
void tabbrowser::createTabMenu()
{m_pTabMenu new QMenu(this);QAction* pAcSave new QAction(QIcon(:/WPSDemo/resources/save.png), u8保存, m_pTabMenu);m_pTabMenu-addAction(pAcSave);connect(pAcSave, QAction::triggered, [] {QMessageBox::information(this, u8提示, u8你点击了 保存);}); //简单响应了一个保存的其他的都还没做QAction* pAcSaveAs new QAction(QString(u8另存为), m_pTabMenu);m_pTabMenu-addAction(pAcSaveAs);m_pTabMenu-addSeparator(); //这个是QAction之间的横线QAction* pAcShareDoc new QAction(QIcon(:/WPSDemo/resources/share.png), QString(u8分享文档), m_pTabMenu);m_pTabMenu-addAction(pAcShareDoc);QAction* pAcSendToDevice new QAction(QString(u8发送到设备), m_pTabMenu);m_pTabMenu-addAction(pAcSendToDevice);m_pTabMenu-addSeparator();QAction* pAcNewName new QAction(QString(u8重命名), m_pTabMenu);m_pTabMenu-addAction(pAcNewName);QAction* pAcSaveToWPSCloud new QAction(QString(u8保存到WPS云文档), m_pTabMenu);m_pTabMenu-addAction(pAcSaveToWPSCloud);QAction* pAcCloseAll new QAction(QString(u8关闭所有文件), m_pTabMenu);m_pTabMenu-addAction(pAcCloseAll);//删除所有和删除一个是差不多的connect(pAcCloseAll, QAction::triggered, this, tabbrowser::on_closeAllTab);
} 四、标题栏和tab标签的结合
负责标题栏右边的按钮实现最后和tab结合这个很简单的看看代码已经是很熟悉了在这个类里不仅进行ui设计还实现标题栏拖拽功能绘图功能等。
#include CTabTitleWidget.h
#include QHBoxLayout
#include QMouseEvent
#include QStyleOption
#include QPainter#ifdef Q_OS_WIN
#include qt_windows.h
#pragma comment(lib, user32.lib)
#endifCTabTitleWidget::CTabTitleWidget(QWidget* parent)
{setStyleSheet(background-color:#E3E4E7);m_pAddBtn new QPushButton(this);m_pAddBtn-setFlat(true);m_pAddBtn-setFixedSize(32, 32);m_pAddBtn-setStyleSheet(background-image:url(:/WPSDemo/resources/add.svg));m_pEmptyWidget new QWidget(this);m_pUserBtn new QPushButton(this);m_pUserBtn-setFlat(true);m_pUserBtn-setFixedSize(32, 32);m_pUserBtn-setStyleSheet(background-image:url(:/WPSDemo/resources/user));m_pMinBtn new QPushButton(this);m_pMinBtn-setFlat(true);m_pMinBtn-setFixedSize(32, 32);m_pMinBtn-setStyleSheet(background-image:url(:/WPSDemo/resources/min.svg));m_pMaxBtn new QPushButton(this);m_pMaxBtn-setFlat(true);m_pMaxBtn-setFixedSize(32, 32);m_pMaxBtn-setStyleSheet(background-image:url(:/WPSDemo/resources/max.svg));m_pCloseBtn new QPushButton(this);m_pCloseBtn-setFlat(true);m_pCloseBtn-setFixedSize(32, 32);m_pCloseBtn-setStyleSheet(background-image:url(:/WPSDemo/resources/close.svg));QHBoxLayout* pHLay new QHBoxLayout(this);pHLay-addWidget(m_pAddBtn);pHLay-addWidget(m_pEmptyWidget);this-setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);pHLay-addWidget(m_pUserBtn);pHLay-addSpacing(8);pHLay-addWidget(m_pMinBtn);pHLay-addWidget(m_pMaxBtn);pHLay-addWidget(m_pCloseBtn);pHLay-setContentsMargins(1, 0, 1, 3);setLayout(pHLay);connect(m_pAddBtn, QPushButton::clicked, this, CTabTitleWidget::on_Clicked);connect(m_pMinBtn, QPushButton::clicked, this, CTabTitleWidget::on_Clicked);connect(m_pMaxBtn, QPushButton::clicked, this, CTabTitleWidget::on_Clicked);connect(m_pCloseBtn, QPushButton::clicked, this, CTabTitleWidget::on_Clicked);
}CTabTitleWidget::~CTabTitleWidget()
{
}void CTabTitleWidget::setEmptyWidgetWidth(int w)
{m_pEmptyWidget-setMinimumWidth(w);
}void CTabTitleWidget::paintEvent(QPaintEvent* event)
{QStyleOption opt;opt.init(this);QPainter p(this);style()-drawPrimitive(QStyle::PE_Widget, opt, p, this);QWidget::paintEvent(event);
}void CTabTitleWidget::mousePressEvent(QMouseEvent* event)
{if (ReleaseCapture()){QWidget* pWindow this-window();if (pWindow-isTopLevel()){SendMessage(HWND(pWindow-winId()), WM_SYSCOMMAND, SC_MOVE HTCAPTION, 0);}}event-ignore();
}void CTabTitleWidget::mouseDoubleClickEvent(QMouseEvent* event)
{emit m_pMaxBtn-clicked();
}void CTabTitleWidget::on_Clicked()
{QPushButton* pButton qobject_castQPushButton*(sender());QWidget* pWindow this-window();if (pWindow-isTopLevel()){if (pButton m_pAddBtn){emit sig_addtab();}else if (pButton m_pMinBtn){pWindow-showMinimized();}else if (pButton m_pMaxBtn){pWindow-isMaximized() ? pWindow-showNormal() : pWindow-showMaximized();}else if (pButton m_pCloseBtn){emit sig_close();}}
} 都看到这里了点个赞再走呗朋友~
加油吧预祝大家变得更强