Qt功能区:Ribbon使用

发布于:2025-05-16 ⋅ 阅读:(13) ⋅ 点赞:(0)

1. Ribbon功能区介绍

Ribbon是把菜单栏和工具栏合并了,并通过一个tab控件进行展示,Ribbon是无法简单的使用Tab+Toolbar替代的,涉及到很多细节问题,SARibbon在设计时参考了MFC Ribbon接口的命名风格,标签页称之为Category(种类),每个Category下面有多个pannel(面板),面板下面管理着toolbutton,pannel有点类似传统的Toolbar,其层次结构如下图所示,这些命名参考了MFC的ribbon界面类。
在这里插入图片描述

  • Category 类别,代表一个标签所呈现的内容,对应SARibbonCategory
  • Context Category 上下文类别,这个是一种特殊的类别,它正常不显示,需要基于上下文判断是否应该显示,最常用的就是word中插入图片后,会有图片修改相关的标签出现,如果没选中图片,这个标签就消失,这个就是上下文类别,对应SARibbonContextCategory
  • Pannel 面板,这个是一组菜单的集合,类似一个Toolbar,对应SARibbonPannel
  • Application Button 应用按钮,标签栏最左边的按钮(word就是对应文件按钮),这个按钮会触发一些特殊的页面或菜单,对应SARibbonApplicationButton,可以隐藏
  • Quick Access Bar 快速响应栏,位于最顶部的一个简单工具栏,用于放置一些常用的action,对应SARibbonQuickAccessBar
  • Gallery 预览控件,这是Ribbon最吸引眼球的控件,用直观的图像把功能显示出来,甚至有些会根据上下文进行实时渲染,典型的就是word开始标签下的样式选择,对应SARibbonGallery

SARibbonBar的层次如下图所示:
在这里插入图片描述

1.1 样式

SARibbonBar::OfficeStyle Ribbon模式示例:
在这里插入图片描述
在这里插入图片描述

2. 基本功能区设置

2.1 安装动态库(推荐)

安装静态库中,将自身程序结构变得复杂,影响编写程序的整体性。
将动态库文件拷贝在项目的子文件夹中:
在这里插入图片描述
在项目中配置:

  1. 配置属性 → VC++目录 → 包含目录:头文件位置
  2. 链接器 → 常规 → 附加库目录:lib文件位置
  3. 链接器 → 输入 → 附加依赖项:.lib文件名称

部署动态库,将.dll复制到以下任一位置:

  1. 项目的运行程序目录下
  2. 系统PATH包含的目录
  3. 与可执行文件相同的目录

2.2 在MainWindow中使用Ribbon

操作步骤:

  1. 修改主窗口的父类
    要MainWindow中使用SARibbon,需要把QMainWindow替换为SARibbonMainWindow,SARibbonMainWindow修改了QMainWindow对menubar的渲染方式。如下图所示:
//h文件中
#include "SARibbonMainWindow.h"
class QtMainWindowRibbon : public SARibbonMainWindow
{
    Q_OBJECT

public:
    QtMainWindowRibbon(QWidget *parent = nullptr);
    ~QtMainWindowRibbon();

private:
    Ui::QtMainWindowRibbonClass *ui;
};

//cpp文件中
QtMainWindowRibbon::QtMainWindowRibbon(QWidget *parent)
    : SARibbonMainWindow(parent)
    , ui(new Ui::QtMainWindowRibbonClass())
{
    ui->setupUi(this);
}
  1. 在Qt Designer中删除菜单栏
    在这里插入图片描述
    基本框架显示效果如下如所示:
    在这里插入图片描述

2.3 在QWidget中使用SARibbonBar

SARibbonBar支持在QWidget上使用。在Dialog中使用,测试不可用。

#include "SARibbonWidget.h"

class RibbonWidget : public SARibbonWidget
{
 Q_OBJECT
public:
    RibbonWidget(QWidget* parent = nullptr);
};

SARibbonWidget类提供了setWidget方法,可以嵌入任意的widget

RibbonWidget::RibbonWidget(QWidget* parent) : SARibbonWidget(parent)
{
    // 获取SARibbonBar
    SARibbonBar* ribbonbar = ribbonBar();
    // QWidget模式下,没有必要再显示标题
    ribbonbar->setTitleVisible(false);
    // QWidget模式下,直接使用紧凑模式效果更好
    ribbonbar->setRibbonStyle(SARibbonBar::RibbonStyleCompactThreeRow);
    // 取消applicationbutton
    ribbonbar->setApplicationButton(nullptr);
}

在这里插入图片描述

2.4 创建Category和Pannel

创建ribbon的顺序是:先创建类别(Category),再创建面板(Pannel),最后创建对应的toolbutton(action)

  1. 使用SARibbonBar::addCategoryPage把Category添加到SARibbonBar中;
  2. 使用SARibbonCategory::addPannel把Pannel添加到Category中;
  3. 使用SARibbonPannel::addAction可以在Pannel上添加action。
	SARibbonBar *ribbon = ribbonBar();
    //添加主标签页 - 通过addCategoryPage工厂函数添加
    SARibbonCategory* categoryMain = ribbon->addCategoryPage(tr("Main"));
    //使用addPannel函数来创建SARibbonPannel,效果和new SARibbonPannel再addPannel一样
    SARibbonPannel* pannel1 = categoryMain->addPannel("Panel 1");
    QAction* actSave = new QAction(this);
    actSave->setText("save");
    actSave->setIcon(QIcon(":/File/save"));
    actSave->setObjectName("actSave");  // 为QObject 及其子类的对象设置一个唯一的名称,这个名称可以通过 objectName() 方法获取。
    //actSave->setShortcut(QKeySequence(QLatin1String("Ctrl+S")));
    actSave->setShortcut(QKeySequence(tr("Ctrl+S")));   //确保适应不用的语言,或者使用actSave->setShortcut(QKeySequence::Save);
    pannel1->addLargeAction(actSave);

    //信号槽
    connect(actSave, &QAction::triggered, this, [=]() {
            QMessageBox::about(this, "about", u8"保存文件!!!");
        }
    );

在这里插入图片描述
Note:Ribbon的图标有大有小,通过addLargeAction、addMediumAction、addSmallAction可以组合出不同的布局样式

2.5 ContextCategory 上下文标签

所谓上下文标签是指在特殊情况下才出现的标签/标签组,例如office word在选中图片时会出现图片编辑的上下文标签,如下图所示:
在这里插入图片描述

  • SARibbon中上下文标签对应的类为SARibbonContextCategory

创建

上下文标签一般在程序初始化的时候就创建好,平时隐藏,等待需要显示的时候再显示,创建上下文标签如下:
由于上下文标签需要使用时唤起,因此,用一个成员变量保存起来是一个比较好的选择,当然也可以遍历查找(SARibbonBar::contextCategoryList可以遍历所有的SARibbonContextCategory)

头文件:

SARibbonContextCategory* m_contextCategory;

CPP文件:

// 上下文标签
	SARibbonBar* ribbon = ribbonBar();
	mContextCategory    = ribbon->addContextCategory(tr("context"), QColor(), 1);

	SARibbonCategory* contextCategoryPage1 = mContextCategory->addCategoryPage(tr("Page1"));
	createContextCategoryPage1(contextCategoryPage1);

	SARibbonCategory* contextCategoryPage2 = mContextCategory->addCategoryPage(tr("Page2"));
	createContextCategoryPage2(contextCategoryPage2);

由SARibbonContextCategory创建的SARibbonCategory归SARibbonContextCategory管理,只有SARibbonContextCategory“显示了”,其管理的SARibbonCategory才显示,注意: SARibbonContextCategory并不是一个窗口,所以,它的“显示”打了引号。

要显示一个上下文只需要调用SARibbonBar::showContextCategory/SARibbonBar::hideContextCategory即可:

void MainWindow::onShowContextCategory(bool on)
{
    if (on) {
        this->ribbonBar()->showContextCategory(m_contextCategory);
    } else {
        this->ribbonBar()->hideContextCategory(m_contextCategory);
    }
}

注意: 如果要删除contextCategory需要调用SARibbonBar::destroyContextCategory,而不是直接delete,调用SARibbonBar::destroyContextCategory之后无需再对ContextCategory的指针delete

this->ribbonBar()->destroyContextCategory(this->m_contextCategory);

2.6 ApplicationButton

ribbon界面左上角有个特殊且明显的按钮,称之为applicationButton,这个按钮一般用于调出菜单,SARibbonBar在构造时默认就创建了applicationButton,可以通过如下方式设置其文字:

SARibbonBar* ribbon = ribbonBar();
	if (!ribbon) {
		return;
	}
	QAbstractButton* btn = ribbon->applicationButton();
	if (!btn) {
		//! cn: SARibbonBar默认就会创建一个SARibbonApplicationButton,因此,在正常情况下,这个位置不会进入
		btn = new SARibbonApplicationButton(this);
		ribbon->setApplicationButton(btn);
	}
    btn->setText(("  &File  ")); 

默认的applicationButton继承自SARibbonApplicationButton,而SARibbonApplicationButton继承自QPushButton,因此你可以对其进行QPushButton所有的操作,如果想设置自己的Button作为applicationButton也是可以的,只需要调用SARibbonBar::setApplicationButton函数即可。

2.7 QuickAccessBar和rightButtonGroup

QuickAccessBar是左上角的快速工具栏,rightButtonGroup是右上角的快速工具栏,在office模式下分左右两边,在wps模式下,左右将合起来,统一放到右边。
在这里插入图片描述
SARibbon中:

  1. QuickAccessBar对应SARibbonQuickAccessBar类
  2. rightButtonGroup对应SARibbonButtonGroupWidget类

SARibbonBar在初始化时会默认创建QuickAccessBar和RightButtonGroup,通过SARibbonBar::quickAccessBar和SARibbonBar::rightButtonGroup即可获取其指针进行操作,示例如下:

// 创建QAction
QAction* QtMainWindowRibbon::createAction(const QString& text, const QString& iconurl, const QString& objName)
{
    QAction* act = new QAction(this);
    act->setText(text);
    act->setIcon(QIcon(iconurl));
    act->setObjectName(objName);
    return act;
}


// 创建QuickAccess工具栏
void QtMainWindowRibbon::initQuickAccessBar()
{
    //获取功能区工具栏
    SARibbonBar* ribbon = ribbonBar();
    SARibbonQuickAccessBar* quickAccessBar = ribbon->quickAccessBar();
    quickAccessBar->addAction(createAction("save", ":/File/save", "save-quickbar"));
    quickAccessBar->addSeparator();
    quickAccessBar->addAction(createAction("undo", ":/File/undo", "undo"));
    quickAccessBar->addAction(createAction("redo", ":/File/redo", "redo"));
    quickAccessBar->addSeparator();
}


// 创建RightButtonGruop
void QtMainWindowRibbon::initRightButtonGroup()
{
    //获取功能区工具栏
    SARibbonBar* ribbon = ribbonBar();
    SARibbonButtonGroupWidget* rightBar = ribbon->rightButtonGroup();
    QAction* actionHelp = createAction("help", ":/File/help", "help");
    connect(actionHelp, &QAction::triggered, this, [this]() {
        QMessageBox::information(this,
            tr("infomation"),
            tr("\n ==============="
                "\n SARibbonBar version:%1"
                "\n ===============")
            .arg(SARibbonBar::versionString()));
        });
    rightBar->addAction(actionHelp);
}

在这里插入图片描述

3. 样式设置

3.1SARibbonBar布局方案

SARibbon支持4种ribbon布局方案,布局方案参考了office的ribbon风格和WPS的ribbon风格,布局方案的切换可 通过***void SARibbonBar::setRibbonStyle(RibbonStyle v)***实现。
office模式是最常见的ribbon模式,tab和标题栏占用位置较多,WPS设计的ribbon模式进行了改良,它为了减小ribbon的高度,把标签和标题栏设置在一起,这样减少了一个标题栏高度,有效利用了垂直空间,同时还把pannel的按钮布局由最大摆放3个变为摆放两个,进一步压缩了垂直空间。

对比

office的word界面和WPS Word界面截图对比
在这里插入图片描述
在正常屏幕下,WPS 样式会比 Office 样式减少至少30像素左右的垂直高度,相比1920*1080的屏幕来说,相当于节约了接近3%的垂直空间。

SARibbon中把带有标题栏的称之为宽松布局(Loose),宽松布局的各个元素如下图排列,这个布局和office的默认布局是一致的。
在这里插入图片描述

SARibbon中把带有标题栏和tab结合一起的布局方式称之为紧凑布局(Compact),紧凑布局的各个元素如下图排列:
在这里插入图片描述

布局方式

SARibbonBar提供了setRibbonStyle函数,可以定义当前的布局方案,枚举SARibbonBar::RibbonStyle定义了四种布局方案:
在这里插入图片描述

窗口尺寸

在这里插入图片描述

实例

SARibbonPannel* pannelStyle = categoryMain->addPannel(tr(u8"功能区样式设置"));
    //窗口功能区样式设置
    QButtonGroup* g = new QButtonGroup(categoryMain);
    QRadioButton* r = new QRadioButton();
    r->setText(tr("use office style"));
    r->setObjectName(("use office style"));
    r->setWindowTitle(r->text());
    r->setChecked(true);
    pannelStyle->addSmallWidget(r);
    g->addButton(r, SARibbonBar::RibbonStyleLooseThreeRow);

    r = new QRadioButton();
    r->setObjectName(("use wps style"));
    r->setText(tr("use wps style"));
    r->setWindowTitle(r->text());
    r->setChecked(false);
    pannelStyle->addSmallWidget(r);
    g->addButton(r, SARibbonBar::RibbonStyleCompactThreeRow);

    r = new QRadioButton();
    r->setObjectName(("use office 2row style"));
    r->setText(tr("use office 2 row style"));
    r->setWindowTitle(r->text());
    r->setChecked(false);
    pannelStyle->addSmallWidget(r);
    g->addButton(r, SARibbonBar::RibbonStyleLooseTwoRow);

    r = new QRadioButton();
    r->setObjectName(("use wps 2row style"));
    r->setText(tr("use wps 2row style"));
    r->setWindowTitle(r->text());
    r->setChecked(false);
    pannelStyle->addSmallWidget(r);
    g->addButton(r, SARibbonBar::RibbonStyleCompactTwoRow);

    connect(g, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::idClicked), this, &QtMainWindowRibbon::onStyleClicked);

void QtMainWindowRibbon::onStyleClicked(int id)
{
    SARibbonBar::RibbonStyles ribbonStyle = static_cast<SARibbonBar::RibbonStyles>(id);
    ribbonBar()->setRibbonStyle(ribbonStyle);
    //mActionWordWrap->setChecked(SARibbonToolButton::isEnableWordWrap());
}

在这里插入图片描述

3.2 SARibbonBar文字换行,及图标大小

通过SARibbonBar::setEnableWordWrap函数可以控制SARibbonBar的文字是否换行,SARibbonBar的高度是固定的,文字是否换行会影响图标显示的大小,因此,如果你想图标看起来更大,可以设置文字不换行。
在SARibbonBar::RibbonStyleCompactTwoRow的布局模式下,文字不换行的显示效果如下:

SARibbonBar文字设置为不换行后,会使图标的显示空间变得更大。

SARibbonPannel* pannelStyle = categoryMain->addPannel(tr(u8"功能区样式设置"));
    //设置功能区图标换行操作
    QAction * actWordWrap = createAction(tr(u8"名称换行"), ":/File/wordWrap","wordWarp");
    actWordWrap->setCheckable(ribbonBar()->isEnableWordWrap());
    pannelStyle->addLargeAction(actWordWrap);
    connect(actWordWrap, &QAction::triggered, this, [this](bool b) {
        this->ribbonBar()->setEnableWordWrap(b);
        });

3.3 不同的“按钮”布局方式

SARibbonPannel提供了三个添加action的方法:

  1. addLargeAction
  2. addMediumAction
  3. addSmallAction
    在标准的pannel中,一个action(按钮)有3种布局,以office word为例,pannel的三种布局其实是所占行数:
    第一种,占满整个pannel,称之为large
    第二种,一个pannel下可以放置2个按钮,称之为medium
    第三种,一个pannel放置3个按钮,称之为samll

3行或2行模式

在这里插入图片描述
在这里插入图片描述

枚举SARibbonPannelItem::RowProportion是为了表征每个窗体在pannel所占行数的情况,在pannel布局中会常用到,这个枚举定义如下:

/**
  * @brief 定义了行的占比,ribbon中有large,media和small三种占比
  */
enum RowProportion {
    None            ///< 为定义占比,这时候将会依据expandingDirections来判断,如果能有Qt::Vertical,就等同于Large,否则就是Small
    , Large         ///< 大占比,一个widget的高度会充满整个pannel
    , Medium        ///< 中占比,在@ref SARibbonPannel::pannelLayoutMode 为 @ref SARibbonPannel::ThreeRowMode 时才会起作用,且要同一列里两个都是Medium时,会在三行中占据两行
    , Small         ///< 小占比,占SARibbonPannel的一行,Medium在不满足条件时也会变为Small,但不会变为Large
};

SARibbonPannel里管理的每个action都会带有一个私有的属性(SARibbonPannelItem::RowProportion),这个属性决定了这个action在pannel里的布局


网站公告

今日签到

点亮在社区的每一天
去签到