Ribbon参考了开源项目:https://github.com/martijnkoopman/Qt-Ribbon-Widget
其代码保护3个功能8文件,实现了自定义QTabWidget添加按钮分组及按钮
代码如下:
TabContentGroup
#ifndef TABCONTENTGROUP_H
#define TABCONTENTGROUP_H
#include <QWidget>
#include <QToolButton>
namespace Ui {
class TabContentGroup;
}
class TabContentGroup : public QWidget
{
Q_OBJECT
public:
explicit TabContentGroup(QWidget *parent = nullptr);
virtual ~TabContentGroup();
void setTitle(const QString& title);
QString getTitle() const;
int buttonCount() const;
void addButton(QToolButton* button);
void removeButton(QToolButton* button);
private:
Ui::TabContentGroup *ui;
QString m_title;
};
#endif // TABCONTENTGROUP_H
实现
#include "tabcontentgroup.h"
#include "ui_tabcontentgroup.h"
TabContentGroup::TabContentGroup(QWidget *parent) :
QWidget(parent),
ui(new Ui::TabContentGroup),
m_title("")
{
ui->setupUi(this);
}
TabContentGroup::~TabContentGroup()
{
delete ui;
}
void TabContentGroup::setTitle(const QString& title)
{
m_title = title;
ui->groupName->setText(m_title);
}
QString TabContentGroup::getTitle() const
{
return m_title;
}
int TabContentGroup::buttonCount() const
{
return ui->groupHorizontalLayou->count();
}
void TabContentGroup::addButton(QToolButton* button)
{
button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
button->setMaximumSize(48, 48);
button->setAutoRaise(true);
button->setIconSize(QSize(32, 32));
button->setEnabled(true);
button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
ui->groupHorizontalLayou->addWidget(button);
}
void TabContentGroup::removeButton(QToolButton* button)
{
ui->groupHorizontalLayou->removeWidget(button);
}
ui文件参考原项目
TabContent
#ifndef TABCONTENT_H
#define TABCONTENT_H
#include <QWidget>
#include <QToolButton>
namespace Ui {
class TabContent;
}
class TabContent : public QWidget
{
Q_OBJECT
public:
explicit TabContent(QWidget *parent = nullptr);
virtual ~TabContent();
void addGroup(const QString& groupName);
void removeGroup(const QString& groupName);
int groupCount() const;
void addButton(const QString& groupName, QToolButton* button);
void removeButton(const QString& groupName, QToolButton* button);
private:
Ui::TabContent *ui;
};
#endif // TABCONTENT_H
实现
#include "tabcontent.h"
#include "ui_tabcontent.h"
#include "tabcontentgroup.h"
TabContent::TabContent(QWidget *parent) :
QWidget(parent),
ui(new Ui::TabContent)
{
ui->setupUi(this);
}
TabContent::~TabContent()
{
delete ui;
}
void TabContent::addGroup(const QString& groupName)
{
TabContentGroup* group = new TabContentGroup(this);
group->setTitle(groupName);
ui->tabContentHorizontalLayout->addWidget(group);
}
void TabContent::removeGroup(const QString& groupName)
{
// 遍历分组,根据标题获取分组
for (int i = 0; i < ui->tabContentHorizontalLayout->count(); i++)
{
TabContentGroup* group = static_cast<TabContentGroup*>(ui->tabContentHorizontalLayout->itemAt(i)->widget());
if (group->getTitle().toLower() == groupName.toLower())
{
ui->tabContentHorizontalLayout->removeWidget(group);
delete group;
break;
}
}
}
int TabContent::groupCount() const
{
return ui->tabContentHorizontalLayout->count();
}
void TabContent::addButton(const QString& groupName, QToolButton* button)
{
TabContentGroup* tabGroup = nullptr;
// 遍历分组,根据名称获取当前分组
for (int i = 0; i < ui->tabContentHorizontalLayout->count(); i++)
{
TabContentGroup* group = static_cast<TabContentGroup*>(ui->tabContentHorizontalLayout->itemAt(i)->widget());
if (group->getTitle().toLower() == groupName.toLower())
{
tabGroup = group;
break;
}
}
if (tabGroup == nullptr)
{
// 如果没找到,先添加分组
addGroup(groupName);
// 再添加按钮
addButton(groupName, button);
}
else
{
// 如果找到了,直接添加按钮到分组
tabGroup->addButton(button);
}
}
void TabContent::removeButton(const QString& groupName, QToolButton* button)
{
TabContentGroup* tabGroup = nullptr;
// 遍历分组,根据名称获取当前分组
for (int i = 0; i < ui->tabContentHorizontalLayout->count(); i++)
{
TabContentGroup* group = static_cast<TabContentGroup*>(ui->tabContentHorizontalLayout->itemAt(i)->widget());
if (group->getTitle().toLower() == groupName.toLower())
{
tabGroup = group;
break;
}
}
if (tabGroup != nullptr)
{
// 如果找到了,则移除按钮
tabGroup->removeButton(button);
// 如果分组没有按钮了,则移除分组
if (tabGroup->buttonCount() == 0)
{
removeGroup(groupName);
}
}
}
ui文件参考原项目
TabWidget
#ifndef TABWIDGET_H
#define TABWIDGET_H
#include <QTableWidget>
#include <QToolButton>
class TabWidget : public QTabWidget
{
Q_OBJECT
public:
TabWidget(QWidget* parent);
void addTab(const QString& tabName);
void addTab(const QIcon& tabIcon, const QString& tabName);
void removeTab(const QString& tabName);
void addGroup(const QString& tabName, const QString& groupName);
void addButton(const QString& tabName, const QString& groupName, QToolButton* button);
void removeButton(const QString& tabName, const QString& groupName, QToolButton* button);
};
#endif // TABWIDGET_H
实现
#include "tabwidget.h"
#include "tabcontent.h"
TabWidget::TabWidget(QWidget* parent) : QTabWidget(parent)
{
}
void TabWidget::addTab(const QString& tabName)
{
TabContent* tabContent = new TabContent(this);
QTabWidget::addTab(tabContent, tabName);
}
void TabWidget::addTab(const QIcon& tabIcon, const QString& tabName)
{
TabContent* tabContent = new TabContent(this);
QTabWidget::addTab(tabContent, tabIcon, tabName);
}
void TabWidget::removeTab(const QString& tabName)
{
for (int i = 0; i < count(); i++)
{
if (tabText(i).toLower() == tabName.toLower())
{
QWidget* tab = QTabWidget::widget(i);
QTabWidget::removeTab(i);
delete tab;
break;
}
}
}
void TabWidget::addGroup(const QString& tabName, const QString& groupName)
{
QWidget* tab = nullptr;
//遍历tab,根据名称获取当前tab
for (int i = 0; i < count(); i++)
{
if (tabText(i).toLower() == tabName.toLower())
{
tab = QTabWidget::widget(i);
break;
}
}
if (tab == nullptr)
{
// 如果没找到,则添加tab
addTab(tabName);
// 再添加group
addGroup(tabName, groupName);
}
else
{
// 如果找到了,则添加group
TabContent* tabContent = static_cast<TabContent*>(tab);
tabContent->addGroup(groupName);
}
}
void TabWidget::addButton(const QString& tabName, const QString& groupName, QToolButton* button)
{
QWidget* tab = nullptr;
//遍历tab,根据名称获取当前tab
for (int i = 0; i < count(); i++)
{
if (tabText(i).toLower() == tabName.toLower())
{
tab = QTabWidget::widget(i);
break;
}
}
if (tab == nullptr)
{
// 如果没找到,先添加tab
addTab(tabName);
// 再添加button
addButton(tabName, groupName, button);
}
else
{
// 如果找到了,添加button到当前group
TabContent* tabContent = static_cast<TabContent*>(tab);
tabContent->addButton(groupName, button);
}
}
void TabWidget::removeButton(const QString& tabName, const QString& groupName, QToolButton* button)
{
QWidget* tab = nullptr;
//遍历tab,根据名称获取当前tab
for (int i = 0; i < count(); i++)
{
if (tabText(i).toLower() == tabName.toLower())
{
tab = QTabWidget::widget(i);
break;
}
}
if (tab != nullptr)
{
// 如果找到了,则移除按钮
TabContent* tabContent = static_cast<TabContent*>(tab);
tabContent->removeButton(groupName, button);
// 如果分组下没有按钮了,则移除分组
if (tabContent->groupCount() == 0)
{
tabContent->removeGroup(groupName);
}
}
}
自定义QMenuBar时,QtCreater的没法选择QMenuBar,可以把ui做好后,使用vscode把ui的基类改为QMenuBar。这个文件很简单,就是一个QMenuBar下面添加一个QTabWidget,并提升为TabWidget。
在QMainWindow中建立菜单时需要注意,由于需要tab, gourp, button 共3级,所以添加菜单时需要添加三级,既主菜单为一级,然后是子菜单第二级, 子菜单下再添加子菜单为第三级。
菜单添加好后在自定义QMenuBar中初始化tab
QMenuBar* menuBar = window->menuBar();
// 菜单需要建3级,分别对应tab的标题, tab内的group的标题,以及tab内的button
if (menuBar != nullptr)
{
// 第一级,用于tab的标题
for (QAction* mainMenu : menuBar->actions())
{
QString tabName = mainMenu->text();
QIcon tabIcon = mainMenu->icon();
ui->tabWidget->addTab(tabIcon, tabName);
QMenu* secondMenus = mainMenu->menu();
if (!secondMenus->isEmpty())
{
// 第二级,用于tab内的group标题
for (QAction* secondMenu : secondMenus->actions())
{
QString groupName = secondMenu->text();
QMenu* thirdMenus = secondMenu->menu();
if (!thirdMenus->isEmpty())
{
for (QAction* thirdMenu : thirdMenus->actions())
{
QString buttonName = thirdMenu->text();
QToolButton* button = new QToolButton;
button->setText(buttonName);
button->setToolTip(buttonName);
button->setDefaultAction(thirdMenu);
ui->tabWidget->addButton(tabName, groupName, button);
}
}
}
}
menuBar->removeAction(mainMenu);
}
}
完了后,可能需要点效果,就是类似word那样的双击显示或隐藏tab内容
QTabBar有个信号,:
voidQTabBar::tabBarDoubleClicked(intindex)
This signal is emitted when the user double clicks on a tab at index.
通过这个可以实现双击显示或隐藏,当然,还得加点动画效果
int startHeight;
int endHeight;
if (ui->tabWidget->currentWidget()->isHidden())
{
ui->tabWidget->currentWidget()->show();
startHeight = TAB_MIN_HEIGHT;
endHeight = TAB_MAX_HEIGHT;
}
else
{
ui->tabWidget->currentWidget()->hide();
startHeight = TAB_MAX_HEIGHT;
endHeight = TAB_MIN_HEIGHT;
}
QPropertyAnimation *animation = new QPropertyAnimation(this, "minimumHeight");
animation->setDuration(200);
animation->setStartValue(startHeight);
animation->setEndValue(endHeight);
animation->start();
完整代码:
#ifndef MENUBAR_H
#define MENUBAR_H
#include <QMenuBar>
#include <QMainWindow>
namespace Ui {
class MenuBar;
}
class MenuBar : public QMenuBar
{
Q_OBJECT
public:
explicit MenuBar(QWidget *parent = nullptr);
~MenuBar();
void initMenuBar(QMainWindow* window);
private slots:
void tabBarDoubleClicked(int index);
private:
Ui::MenuBar *ui;
};
#endif // MENUBAR_H
实现
#include "menubar.h"
#include "ui_menubar.h"
#include <QAction>
#include <QMenu>
#include <QToolButton>
#include <QTabBar>
#include <QPropertyAnimation>
const int TAB_MAX_HEIGHT = 102;
const int TAB_MIN_HEIGHT = 38;
MenuBar::MenuBar(QWidget *parent) :
QMenuBar(parent),
ui(new Ui::MenuBar)
{
ui->setupUi(this);
setMinimumHeight(TAB_MAX_HEIGHT);
connect(ui->tabWidget->tabBar(), &QTabBar::tabBarDoubleClicked, this, &MenuBar::tabBarDoubleClicked);
}
MenuBar::~MenuBar()
{
delete ui;
}
void MenuBar::initMenuBar(QMainWindow* window)
{
QMenuBar* menuBar = window->menuBar();
// 菜单需要建3级,分别对应tab的标题, tab内的group的标题,以及tab内的button
if (menuBar != nullptr)
{
// 第一级,用于tab的标题
for (QAction* mainMenu : menuBar->actions())
{
QString tabName = mainMenu->text();
QIcon tabIcon = mainMenu->icon();
ui->tabWidget->addTab(tabIcon, tabName);
QMenu* secondMenus = mainMenu->menu();
if (!secondMenus->isEmpty())
{
// 第二级,用于tab内的group标题
for (QAction* secondMenu : secondMenus->actions())
{
QString groupName = secondMenu->text();
QMenu* thirdMenus = secondMenu->menu();
if (!thirdMenus->isEmpty())
{
for (QAction* thirdMenu : thirdMenus->actions())
{
QString buttonName = thirdMenu->text();
QToolButton* button = new QToolButton;
button->setText(buttonName);
button->setToolTip(buttonName);
button->setDefaultAction(thirdMenu);
ui->tabWidget->addButton(tabName, groupName, button);
}
}
}
}
menuBar->removeAction(mainMenu);
}
}
}
void MenuBar::tabBarDoubleClicked(int index)
{
Q_UNUSED(index);
int startHeight;
int endHeight;
if (ui->tabWidget->currentWidget()->isHidden())
{
ui->tabWidget->currentWidget()->show();
startHeight = TAB_MIN_HEIGHT;
endHeight = TAB_MAX_HEIGHT;
}
else
{
ui->tabWidget->currentWidget()->hide();
startHeight = TAB_MAX_HEIGHT;
endHeight = TAB_MIN_HEIGHT;
}
QPropertyAnimation *animation = new QPropertyAnimation(this, "minimumHeight");
animation->setDuration(200);
animation->setStartValue(startHeight);
animation->setEndValue(endHeight);
animation->start();
}
使用
MenuBar *menuBar = new MenuBar(this);
menuBar->initMenuBar(this);
setMenuBar(menuBar);
效果
本文暂时没有评论,来添加一个吧(●'◡'●)