跳转至

创建Ribbon界面

Ribbon组件创建流程

从获取 SARibbonBar 到创建各类 UI 元素,遵循以下层级递进的创建流程:

flowchart LR
    A[获取 SARibbonBar] --> B[创建 SARibbonCategory]
    B --> C[创建 SARibbonPanel]
    C --> D{选择组件类型}
    B -->|上下文标签| J[addContextCategory + addCategoryPage]
    A --> K[配置 QuickAccessBar]
    A --> L[配置 RightButtonGroup]
    A --> M[配置 ApplicationButton]
    J --> N[showContextCategory/hideContextCategory]

Category(分类页)

创建分类页有两种方式:

方式一:通过ribbonbar添加

1
2
3
4
5
SARibbonBar* ribbon = ribbonBar();
// 直接添加一个名为“Main”的分类页
SARibbonCategory* homeCategory = ribbon->addCategoryPage("Main");
// 如果你需要进行ribbon界面自定义配置工具(SARibbonCustomizeDialog),你必须设置 objectName用于区分
homeCategory->setObjectName("MainCategory");

上面的代码将会添加一个名字为Main的标签页

add-category

方式二:先创建后添加

1
2
3
4
5
6
7
// 先创建一个分类页对象
SARibbonCategory* insertCategory = new SARibbonCategory(this);
insertCategory->setCategoryName("插入");
insertCategory->setObjectName("insertCategory");

// 再将其添加到 RibbonBar
ribbon->addCategoryPage(insertCategory);

Panel(面板)

创建面板并添加动作

面板是category下面的一组功能。您可以通过 CategoryaddPanel 方法创建面板,并通过 addAction 系列方法添加功能按钮

每个category必须有一个panel

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// 在 "主页" 分类下创建一个 "文件" 面板
SARibbonPanel* filePanel = homeCategory->addPanel("文件");
filePanel->setObjectName("filePanel");

// 创建动作
QAction* newAction = new QAction(QIcon(":/new.svg"), "新建", this);
newAction->setObjectName("action_new");
newAction->setShortcut(QKeySequence::New);

// 将动作添加到面板
// addLargeAction: 大按钮,图标+文字
filePanel->addLargeAction(newAction);
// addSmallAction: 小按钮,通常只有图标
QAction* saveAction = new QAction(QIcon(":/save.svg"), "保存", this);
saveAction->setObjectName("action_save");
filePanel->addSmallAction(saveAction);

// 连接信号槽
connect(newAction, &QAction::triggered, [] {
    qDebug() << "New document created.";
});

创建菜单

在 Ribbon 界面中,菜单(Menu)是组织复杂功能的重要手段。SARibbon允许您将菜单以不同风格的按钮形式添加到面板中。主要区别在于按钮的弹出模式 (QToolButton::ToolButtonPopupMode),它决定了用户如何与菜单进行交互

SARibbon 支持3种主要的弹出模式,您可以根据功能需求选择最合适的模式:

  1. DelayedPopup (延迟弹出):

    用户点击按钮,会执行按钮的默认动作,用户长按按钮,菜单才会弹出(长按直至菜单弹出,按钮的默认动作不会执行)。适用场景主要是当按钮的主要功能是执行一个常用操作,菜单提供的是次要或高级选项时才选用此模式

  2. MenuButtonPopup (菜单按钮弹出):

    这是 Ribbon 界面最具特色的模式。按钮会被视觉上分割为上下两部分,点击按钮的上半部分(图标区域)会执行默认动作;点击下半部分(文本或下拉箭头区域)则会直接弹出菜单,不执行默认动作。鼠标悬停时,两部分会有不同的高亮效果。

    这是最推荐的模式,尤其适用于 Office 风格的应用。它清晰地区分了主要操作和次要操作,用户体验最佳。例如,一个“粘贴”按钮,点击图标区域执行标准粘贴,点击下拉箭头区域则弹出“选择性粘贴”、“粘贴为纯文本”等选项。

  3. InstantPopup (即时弹出):

    用户点击按钮的任何部分,都会立即弹出菜单,不会执行按钮的默认动作。这种模式适用于当按钮的功能完全由其下拉菜单定义,没有单一的“默认”操作时。例如,“页面布局”按钮,点击后直接弹出设置页边距、纸张方向等选项的菜单。

SARibbon添加菜单有两种方法,第一种是调用addXXAction函数:

1
2
3
4
5
6
// 把action加入到panel,并以小图标显示
void addSmallAction(QAction* action, QToolButton::ToolButtonPopupMode popMode);
// 把action加入到panel,并以大图标显示
void addLargeAction(QAction* action, QToolButton::ToolButtonPopupMode popMode);
// 把action加入到panel,在三行模式下会以中图标显示
void addMediumAction(QAction* action, QToolButton::ToolButtonPopupMode popMode);

使用这种方法是action包含了menu,第二个参数明确指定了按钮的样式

下面是使用此方法的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
SARibbonPanel* panelToolButtonStyle = page->addPanel(("sa ribbon toolbutton style"));

QMenu* menu = new QMenu;
//...构建菜单

// DelayedPopup模式
QAction* act = createAction(tr("Delayed\nPopup"), ":/icon/icon/folder-cog.svg");
act->setMenu(menu);
panelToolButtonStyle->addLargeAction(act, QToolButton::DelayedPopup);
connect(act, &QAction::triggered, this, &MainWindow::onDelayedPopupTriggered);

act = createAction(tr("Menu Button Popup"), ":/icon/icon/folder-star.svg");
act->setMenu(menu);
panelToolButtonStyle->addLargeAction(act, QToolButton::MenuButtonPopup);
connect(act, &QAction::triggered, this, &MainWindow::onMenuButtonPopupTriggered);

act = createAction(tr("Instant Popup"), ":/icon/icon/folder-stats.svg");
act->setMenu(menu);
panelToolButtonStyle->addLargeAction(act, QToolButton::InstantPopup);
connect(act, &QAction::triggered, this, &MainWindow::onInstantPopupTriggered);

上面的代码将会创建如下三个菜单按钮

SARibbon-Toolbutton-Style

这三个按钮共享一个菜单

SARibbon还提供了另外一个接口来快速添加菜单(方法位于SARibbonPanel类):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 添加menu
void addMenu(QMenu* menu,
                SARibbonPanelItem::RowProportion rowProportion,
                QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);
// 添加普通大菜单
void addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);
// 添加中等尺寸菜单按钮
void addMediumMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);
// 添加普通小按钮菜单
void addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);

这几个函数实际利用率menu自身的action进行管理,无需再单独创建一个action

注意

这几个方法会修改 menu->menuAction() 的部分属性(icon/text/objectName),如需保留自定义值,请提前设置。

面板的布局占位说明

SARibbon 面板的布局目前有3种占位标志。当您调用 addLargeActionaddMediumActionaddSmallAction 时,您不仅是在添加一个按钮,还在指定它在网格布局中的"占位大小"。

  • Large Action: 高度上占据2行或3行(取决于当前是两行还是三行模式),显示大图标和文字。
  • Medium Action: 高度上占据1行或1.5行的网格(取决于当前是两行还是三行模式),通常显示图标和文字。
  • Small Action: 高度上占据1行

这些行占比在不同的布局方案会有不同的呈现效果

SARibbonPanel支持三种布局方案,分别是3行模式、2行模式和单行模式(v2.8.0 新增),通过SARibbonBar::setRibbonStyle函数你可以设置不同的布局风格

对于3行模式,上诉三种行占位的效果如下图所示

pannelLayout3row

对于2行模式,上诉三种行占位的效果如下图所示

pannelLayout2row

2行模式下medium和small占位(SARibbonPanelItem::RowProportion)是一样的,不做区分。

对于单行模式(v2.8.0 新增),所有按钮排列在同一行内,图标在左侧、文字在右侧横向排列,Large、Medium、Small 占位都等效为 Small。建议搭配 SARibbonBar::setEnableIconRightText(true) 使用。

关于面板按钮的布局,详细可见:Ribbon栏按钮布局说明,以及:SARibbon布局方式

面板犹如一个Toolbar,添加的action最终会以按钮的方式进行渲染,SARibbonBar的提供了许多函数可以统一设置面板的属性:

  • 设置panel按钮图标尺寸:

    1
    2
    3
    4
    // 大按钮图标尺寸
    void setPanelLargeIconSize(const QSize& largeSize);
    // 小按钮图标尺寸
    void setPanelSmallIconSize(const QSize& smallSize);
    
  • 设置panel的一些渲染属性:

    1
    2
    3
    4
    // 设置按钮是否允许换行
    void setEnableWordWrap(bool on);
    // 设置panel是否显示标题栏
    void setEnableShowPanelTitle(bool on);
    
  • 设置panel的一些位置尺寸:

    1
    2
    3
    4
    5
    6
    // 设置panel与panel之间的间距
    void setPanelSpacing(int n);
    // 设置panel的标题栏高度
    void setPanelTitleHeight(int h);
    // 按钮的最大宽高比,这个系数决定按钮的最大宽度,系数越大,按钮能显示的越宽
    void setButtonMaximumAspectRatio(qreal fac = 1.4);
    

上面的方法会作用到每一个已经设置的panel和对应的按钮

在面板中添加复杂控件 (Widget)

除了 QAction,您还可以直接在面板中添加任何 QWidget,例如组合框、微调框或自定义控件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
SARibbonCategory* page = ribbonBar()->addCategoryPage(tr("Main"));
SARibbonPanel* panelWidgetTest = page->addPanel(tr("widget test"));

QComboBox* com1 = new QComboBox(this);
com1->setWindowTitle(tr("QComboBox test"));
for (int i = 0; i < 40; ++i) {
    com1->addItem(QString("QComboBox test%1").arg(i + 1));
}
com1->setEditable(true);
panelWidgetTest->addSmallWidget(com1);

QComboBox* com2 = new QComboBox(this);
com2->setWindowTitle("ComboBox Editable");
for (int i = 0; i < 40; ++i) {
    com2->addItem(QString("item %1").arg(i + 1));
}
panelWidgetTest->addSmallWidget(com2);


QLineEdit* lineEdit = new QLineEdit(this);
lineEdit->setText("LineEdit");
panelWidgetTest->addSmallWidget(lineEdit);

panelWidgetTest->addSeparator();

QCalendarWidget* calendarWidget = new QCalendarWidget(this);
panelWidgetTest->addLargeWidget(calendarWidget);

上面代码的效果如下:

widget-in-panel

使用按钮组 (Button Group)

按钮组SARibbonButtonGroupWidget 可以将多个小按钮紧密排列在一起,和QToolBar类似,常用于一组相近功能的操作,如文本对齐

SARibbonButtonGroupWidget继承QToolBar,在一个按钮组里的action,你不需要再组个aciton绑定信号,使用QToolBar::actionTriggered信号即可

下面这段代码演示如何创建按钮组,以及如何绑定信号

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 按钮组2
SARibbonButtonGroupWidget* btnGroup2 = new SARibbonButtonGroupWidget(panel1);
btnGroup2->setObjectName("SARibbonButtonGroupWidget2");

QAction* titleAlgnmentRight = createAction(tr("Align Right"), ":/icon/icon/Align-Right.svg");
titleAlgnmentRight->setProperty("align", (int)Qt::AlignRight | Qt::AlignVCenter);
btnGroup2->addAction(titleAlgnmentRight);
QAction* titleAlgnmentLeft = createAction(tr("Align Left"), ":/icon/icon/Align-Left.svg");
titleAlgnmentLeft->setProperty("align", (int)Qt::AlignLeft | Qt::AlignVCenter);
btnGroup2->addAction(titleAlgnmentLeft);
QAction* titleAlgnmentCenter = createAction(tr("Align Center"), ":/icon/icon/Align-Center.svg");
titleAlgnmentCenter->setProperty("align", (int)Qt::AlignCenter);
btnGroup2->addAction(titleAlgnmentCenter);
panel1->addWidget(btnGroup2, SARibbonPanelItem::Medium);
connect(btnGroup2, &SARibbonButtonGroupWidget::actionTriggered, this, &MainWindow::onButtonGroupActionTriggered);

上面的代码生成了如下界面(具体例子可见example/MainWindowExample/mainWindow.cpp,createCategoryOther函数)

button-group

Gallery (画廊)是一个Ribbon特有的控件,用于以网格形式展示带图标的选项,常用于在有限空间显示大量图标动作,例如word的样式选择

SARibbon的Gallery (画廊)对应窗口为SARibbonGallery,通过SARibbonPanel::addGallery即可创建一个Gallery (画廊),此函数返回创建的SARibbonGallery指针

SARibbonGallery可以管理多个动作组,一个动作组对应的类名为SARibbonGalleryGroup,你可以使用SARibbonGallery::addCategoryActions方法快速添加动作组,其参数是动作组标题和动作组的action列表

1
SARibbonGalleryGroup* addCategoryActions(const QString& title, QList< QAction* > actions);

下面这段代码演示了如何创建一个Gallery (画廊),并添加2个动作组

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
QAction MyRibbonMainWindow::createAction(const QString& text, const QString& iconurl){
    QAction* act = new QAction(this);
    act->setText(text);
    act->setIcon(QIcon(iconurl));
    return act;
}

void MyRibbonMainWindow::buildGalleryExample(){
    SARibbonPanel* panelWithGallery = ...;
    ...
    // 创建一个Gallery (画廊)
    SARibbonGallery* gallery = panelWithGallery->addGallery();
    // 添加动作组1
    QList< QAction* > galleryActions1;
    galleryActions1.append(createAction("Document File", ":/gallery-icon/icon/gallery/Document-File.svg"));
    galleryActions1.append(createAction("Download File", ":/gallery-icon/icon/gallery/Download-File.svg"));
    ......
    galleryActions1.append(createAction("File Settings", ":/gallery-icon/icon/gallery/File-Settings.svg"));
    galleryActions1.append(createAction("Presentation File", ":/gallery-icon/icon/gallery/Presentation-File.svg"));
    SARibbonGalleryGroup* group1 = gallery->addCategoryActions(tr("Files"), galleryActions1);
    group1->setGalleryGroupStyle(SARibbonGalleryGroup::IconWithWordWrapText);
    group1->setGridMinimumWidth(80);

    // 添加动作组2
    QList< QAction* > galleryActions2;
    galleryActions2.append(createAction("Photoshop", ":/gallery-icon/icon/gallery/Photoshop.svg"));
    galleryActions2.append(createAction("Internet-Explorer", ":/gallery-icon/icon/gallery/Internet-Explorer.svg"));
    galleryActions2.append(createAction("Illustrator", ":/gallery-icon/icon/gallery/Illustrator.svg"));
    galleryActions2.append(createAction("Google-Maps", ":/gallery-icon/icon/gallery/Google-Maps.svg"));
    galleryActions2.append(createAction("Adobe", ":/gallery-icon/icon/gallery/Adobe.svg"));
    galleryActions2.append(createAction("Word", ":/gallery-icon/icon/gallery/Word.svg"));
    SARibbonGalleryGroup* group2 = gallery->addCategoryActions(tr("Apps"), galleryActions2);
    group2->setGridMinimumWidth(80);
    // 设置当前显示的组
    gallery->setCurrentViewGroup(group1);
}

通过上面代码,创建的gallery效果如下:

saribbon-gallery

此gallery展开后效果如下:

saribbon-gallery-expand

Context Category(上下文标签页)

Context Category 是一种特殊标签页,通常在特定条件下(如选中某个对象)才显示,最常见的就是word中的“图片工具”和“表格工具”,是在选中图片或表格时才出现,这种有条件显示的标签称之为上下文标签

SARibbon的Context Category(上下文标签页)对应窗口为SARibbonContextCategory,通过SARibbonBar::addContextCategory即可创建一个Context Category(上下文标签页),此函数返回创建的SARibbonContextCategory指针

SARibbonContextCategory并不是一个窗口(它的基类是QObject),只是一个标签页管理器,需要再SARibbonContextCategory上添加标签页,通过SARibbonContextCategory::addCategoryPage方法即可在对应的Context Category(上下文标签页)上添加标签页

Context Category(上下文标签页)默认情况下不会显示,需要调用SARibbonBar::showContextCategory方法显示,隐藏上下文标签页则可通过SARibbonBar::hideContextCategory实现,SARibbonContextCategory也带有show/hide槽函数来实现上下文标签页的显示和隐藏

下面这段代码演示了如何创建一个Context Category(上下文标签页),并添加两个标签页

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
//m_contextCategory为MainWindow的成员变量:SARibbonContextCategory* m_contextCategory;

void MainWindow::createContextCategory(){
    SARibbonBar* ribbon = ribbonBar();
    m_contextCategory    = ribbon->addContextCategory(tr("context"), QColor(), 1);

    SARibbonCategory* contextCategoryPage1 = m_contextCategory->addCategoryPage(tr("Page1"));
    //创建contextCategoryPage1对应的内容
    createContextCategoryPage1(contextCategoryPage1);

    SARibbonCategory* contextCategoryPage2 = m_contextCategory->addCategoryPage(tr("Page2"));
    //创建contextCategoryPage2对应的内容
    createContextCategoryPage2(contextCategoryPage2);
}

上面的代码创建完Context Category(上下文标签页)后并不会显示,如果需要显示,你还需在特定条件下触发

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
void MainWindow::onShowContextCategory(bool on)
{
    if (m_contextCategory == nullptr) {
        createContextCategory();
    }
    if (on) {
        m_contextCategory->show();
    } else {
        m_contextCategory->hide();
    }
}

上面的代码效果如下:

SARibbonBar-Context-Category

为了区分上下文标签页和普通的标签页,上下文标签页会有特殊的颜色进行标识,如上图所示。这个标识的颜色可以通过SARibbonBar::setContextCategoryColorList设置

Application Button

Application Button 是 Ribbon 界面左上角的主菜单按钮,通常用于“文件”操作

SARibbon 在创建 SARibbonBar 时,会默认创建一个SARibbonApplicationButton实例作为Application Button。您可以通过 SARibbonBar::applicationButton方法获取该按钮的指针,并对其进行操作,例如设置文本、设置图标、设置快捷键、设置菜单,等等

如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
void MainWindow::createRibbonApplicationButton()
{
    SARibbonBar* ribbon = ribbonBar();
    QAbstractButton* btn = ribbon->applicationButton();
    btn->setText(("&File"));

    SARibbonApplicationButton* appBtn = qobject_cast< SARibbonApplicationButton* >(btn);
    if (appBtn) {
        QMenu* menu = new QMenu(this);
        ...
        appBtn->setMenu(menu);
    }
}

如果你有自定义的按钮,你可以通过 SARibbonBar::setApplicationButton 方法设置 Application Button。如果你不想要Application Button,你可以传入nullptr

1
ribbonBar()->setApplicationButton(nullptr); // 移除按钮

application button可以通过qss设置比较丰富的样式,下面是模仿win7风格的ribbon样式设置的qss演示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
SARibbonApplicationButton{
  color:white;
  border: 1px solid #416ABD;
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
  background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,stop:0 #467FBD, stop:0.5 #2A5FAC,stop:0.51 #1A4088,
stop:1 #419ACF);
}

SARibbonApplicationButton:hover{
  background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,stop:0 #7BB2EB, stop:0.5 #477ECD,stop:0.51 #114ECF,
stop:1 #80E1FF);
}

SARibbonApplicationButton:pressed{
  background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,stop:0 #467BBB, stop:0.5 #2F63AE,stop:0.51 #1C438A,
stop:1 #358BC9);
}

SARibbonApplicationButton:focus{
  outline: none;
}

SARibbonApplicationButton::menu-indicator {
  /*subcontrol-position: right;*/
  width:0px;
}

上面的效果如下:

win7style-application-button

在宽松模式下,Application Button可以设置为垂直扩展,这时候,Application Button将占用标题栏和tab栏的空间

示例:

1
ribbonBar()->setApplicationButtonVerticalExpansion(true);

上面的代码效果如图所示:

set-application-btn-expand

注意

SARibbonBar::setApplicationButtonVerticalExpansion函数会对titleIconWidget的可见性进行调整,如果设置applicationButtonVerticalExpansion=true,那么titleIconWidget会被隐藏,反之,titleIconWidget会被显示
SARibbonBar::setTitleIconVisible函数不会对applicationButtonVerticalExpansion的状态有影响
因此,如果你动态调整applicationButtonVerticalExpansion的状态,如果你需要显示窗口图标,在设置setApplicationButtonVerticalExpansion(false)后,需要调用setTitleIconVisible(true)让窗口图标显示

注意

ApplicationButtonVerticalExpansion仅在宽松模式(SARibbonBar::RibbonStyleLoose)下有效

Application Widget

在许多现代化应用(如 Microsoft Office)中,点击 Application Button 并不会弹出一个简单的下拉菜单,而是会弹出一个全屏或半屏的复杂页面,该页面可以包含最近文件列表、模板选择、账户设置、应用选项等丰富内容

SARibbon提供了SARibbonApplicationWidget,它能自动帮你覆盖主窗口,你的弹出式窗口可以继承SARibbonApplicationWidget来实现

SARibbonApplicationWidget提供了resizeToParent函数来决定如何相对父窗口进行缩放,默认是完全覆盖父窗口,如果你想覆盖一半或者其他尺寸,你可以重写此函数

API摘要

方法名 返回值 说明
SARibbonApplicationWidget(SARibbonMainWindow* parent) 构造 创建应用窗口控件
resizeToParent(const QSize& parentSize) void 相对父窗口缩放(可重写)
eventFilter(QObject*, QEvent*) bool 过滤父窗口事件
showEvent(QShowEvent*) void 处理显示事件
keyPressEvent(QKeyEvent*) void 处理键盘事件(ESC关闭)

使用Application Widget的例子如下:

继承SARibbonApplicationWidget实现自己的窗口

1
2
3
4
5
6
7
class ApplicationWidget : public SARibbonApplicationWidget
{
    Q_OBJECT
public:
    explicit ApplicationWidget(SARibbonMainWindow* parent = nullptr);
    ~ApplicationWidget();
};

在MainWindow中创建Application Widget的成员变量指针m_appWidget,初始化时绑定applicationButton的响应:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
void MainWindow::createRibbonApplicationButton()
{
    SARibbonBar* ribbon = ribbonBar();
    if (!ribbon) {
        return;
    }
    QAbstractButton* btn = ribbon->applicationButton();
    btn->setText(("&File"));
    // 这里演示用SARibbonApplicationWidget实现一个类似office的弹出式窗口
    m_appWidget = new ApplicationWidget(this);
    m_appWidget->hide();
    connect(btn, &QAbstractButton::clicked, this, [ this ](bool c) {
        Q_UNUSED(c);
        this->m_appWidget->show();
    });
}

上面的代码效果如下:

application-widget

Quick Access Bar(快速访问工具栏)

快速访问工具栏位于窗口最顶部,用于放置最常用的操作,如保存、撤销、重做。快速访问工具栏对应的类为SARibbonQuickAccessBar,它继承自QToolBar,你可以和操作工具栏一样使用它

SARibbon默认会创建一个快速访问工具栏,你可以调用SARibbonBar::quickAccessBar函数获取快速访问工具栏的指针,然后对快速访问工具栏进行操作

下面是快速访问工具栏的用法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void MainWindow::createQuickAccessBar()
{
    SARibbonQuickAccessBar* quickAccessBar = ribbonBar()->quickAccessBar();

    QAction* actionSave = new QAction(QIcon(":/icon/icon/save.svg"),"save",this);
    quickAccessBar->addAction(actionSave);
    quickAccessBar->addSeparator();

    QAction* actionUndo = new QAction(QIcon(":/icon/icon/undo.svg"),"undo",this);
    quickAccessBar->addAction(actionUndo);

    QAction* actionRedo = new QAction(QIcon(":/icon/icon/redo.svg"),"redo",this);
    quickAccessBar->addAction(actionRedo);

    quickAccessBar->addSeparator();

    QMenu* menu1 = new QMenu("Presentation File 1", this);
    menu1->setIcon(QIcon(":/icon/icon/presentationFile.svg"));
    // 创建菜单
    ...
    // 创建 QAction
    quickAccessBar->addMenuAction(menu1->menuAction());//效果等同quickAccessBar->addMenuAction(menu1);

    QMenu* menu2 = new QMenu("Presentation File 2", this);
    menu2->setIcon(QIcon(":/icon/icon/presentationFile.svg"));
    // 创建菜单
    ...
    quickAccessBar->addMenuAction(menu2, QToolButton::MenuButtonPopup);
    ...
    mSearchEditor = new QLineEdit(this);
    mSearchEditor->setMinimumWidth(150);
    mSearchEditor->setPlaceholderText("Search");
    quickAccessBar->addWidget(mSearchEditor);
}

上面的代码创建了一个快速访问工具栏,效果如下:

quick-access-bar

Right Button Group(右侧按钮组)

Right Button Group(右侧按钮组)是 Ribbon 界面右上角按钮组,通常用于“帮助”、“设置”、“关于”等操作。Right Button Group(右侧按钮组)对应的类为SARibbonButtonGroupWidget,它继承自QToolBar,你可以和操作工具栏一样使用它

SARibbon默认会创建一个Right Button Group(右侧按钮组),你可以调用SARibbonBar::rightButtonGroup函数获取Right Button Group的指针,然后对它进行操作

下面是Right Button Group的用法:

1
2
3
4
5
6
7
8
9
void MainWindow::createRightButtonGroup()
{
    SARibbonBar* ribbon = ribbonBar();
    SARibbonButtonGroupWidget* rightBar = ribbon->rightButtonGroup();
    QAction* actionHelp                 = new QAction(QIcon(":/icon/icon/help.svg"),"help",this);
    QAction* actionVisible                   = new QAction(QIcon(":/icon/icon/visible-true.svg"),"Visible",this);
    rightBar->addAction(actionHelp);
    rightBar->addAction(actionVisible);
}

Right Button Group(右侧按钮组)效果如下:

right-button-group

Window Button Bar(系统标题栏按钮旁的工具栏)

Window Button Bar(系统标题栏按钮旁的工具栏)是 Ribbon 界面系统最大最小化合关闭按钮组,Window Button Bar对应的类名为SARibbonSystemButtonBar,它默认会创建好窗口需要的最大最小化及关闭按钮,它会自动处理窗口的状态调整系统按钮的显示,SARibbonSystemButtonBar内部有一个SARibbonButtonGroupWidget,提供了addActionaddSeparatoraddWidget等函数,用于在最大最小化旁边添加按钮

你可以通过SARibbonMainWindowwindowButtonBar函数获取SARibbonSystemButtonBar指针

注意

SARibbonSystemButtonBar不是SARibbonBar的子窗口,是SARibbonMainWindow的子窗口

SARibbonSystemButtonBar的使用示例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
void MainWindow::createWindowButtonGroupBar()
{
    SARibbonSystemButtonBar* wbar = windowButtonBar();
    if (!wbar) {
        return;
    }
    QAction* actionLogin = new QAction(QIcon(), "Login",this);
    QAction* actionHelp = new QAction(QIcon(":/icon/icon/help.svg"),"help",this);
    ...
    wbar->addAction(a);
    wbar->addAction(actionHelp);
}

上面代码的效果如下:

window-button-bar

SARibbonMenu 详细用法

SARibbonMenu 是专为 Ribbon 界面设计的菜单类,继承自 QMenu。它可以通过 StyleSheet 独立设置样式而不影响全局的 QMenu 样式,适合在 Ribbon 环境中使用。

与 QMenu 的区别

特性 QMenu SARibbonMenu
样式隔离 通过 QSS 会影响所有 QMenu 仅影响 SARibbonMenu 实例
子菜单类型 返回普通 QMenu 返回 SARibbonMenu
控件支持 支持 addWidget 提供 addWidget 方法

API摘要

方法名 返回值 说明
SARibbonMenu(QWidget* parent) 构造 创建空菜单
SARibbonMenu(const QString& title, QWidget* parent) 构造 创建带标题的菜单
addRibbonMenu(SARibbonMenu* menu) QAction* 添加已存在的 SARibbonMenu 作为子菜单
addRibbonMenu(const QString& title) SARibbonMenu* 创建并添加指定标题的子菜单
addRibbonMenu(const QIcon& icon, const QString& title) SARibbonMenu* 创建并添加带图标和标题的子菜单
addWidget(QWidget* w) QAction* 向菜单中添加自定义控件

代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 创建 SARibbonMenu
SARibbonMenu* mainMenu = new SARibbonMenu(tr("文件操作"), panel);

// 添加普通动作
mainMenu->addAction("新建");
mainMenu->addAction("打开");
mainMenu->addSeparator();

// 添加子菜单(使用 addRibbonMenu)
SARibbonMenu* recentSubmenu = mainMenu->addRibbonMenu(tr("最近文件"));
recentSubmenu->addAction("document1.docx");
recentSubmenu->addAction("document2.docx");

// 添加带图标的子菜单
SARibbonMenu* exportSubmenu = mainMenu->addRibbonMenu(
    QIcon(":/icon/export.svg"), tr("导出"));
exportSubmenu->addAction("PDF");
exportSubmenu->addAction("HTML");

// 添加自定义控件到菜单
QLabel* label = new QLabel(tr("自定义内容"));
label->setStyleSheet("padding: 8px;");
mainMenu->addWidget(label);

// 将菜单关联到面板按钮
actionExport->setMenu(mainMenu);
panel->addLargeAction(actionExport, QToolButton::MenuButtonPopup);

SARibbonGalleryGroup API 详解

SARibbonGalleryGroup 是 Gallery 控件中的动作组,继承自 QListView,负责以网格形式显示和管理一组 SARibbonGalleryItem

枚举类型

GalleryGroupStyle 显示样式

枚举值 说明
IconWithText 图标+文字(文字在一行显示)
IconWithWordWrapText 图标+自动换行文字(仅在 DisplayOneRow 下生效)
IconOnly 仅显示图标

DisplayRow 显示行数

枚举值 说明
DisplayOneRow (1) 显示1行(默认)
DisplayTwoRow (2) 显示2行
DisplayThreeRow (3) 显示3行

API摘要

方法名 返回值 说明
setGalleryGroupStyle(GalleryGroupStyle) void 设置显示样式
galleryGroupStyle() GalleryGroupStyle 获取当前显示样式
setDisplayRow(DisplayRow) void 设置显示行数
displayRow() DisplayRow 获取当前显示行数
setGridMinimumWidth(int) void 设置网格最小宽度(默认0:不限制)
gridMinimumWidth() int 获取网格最小宽度
setGridMaximumWidth(int) void 设置网格最大宽度(默认0:不限制)
gridMaximumWidth() int 获取网格最大宽度
addItem(const QString&, const QIcon&) void 添加项
addItem(SARibbonGalleryItem*) void 添加项对象
addActionItem(QAction*) void 将 QAction 添加为项
addActionItemList(const QList<QAction*>&) void 批量添加 QAction
removeActionItem(QAction*) bool 移除指定 QAction 项
setGroupTitle(const QString&) void 设置组标题
groupTitle() QString 获取组标题
groupModel() SARibbonGalleryGroupModel* 获取底层模型
actionGroup() QActionGroup* 获取管理的 QActionGroup
gridRowCount() int 获取网格行数
gridColumnCount() int 获取网格列数
selectByIndex(int) void 按索引选中项
recalcGridSize() void 重新计算网格大小
preferredHeightForWidth(int) int 获取指定宽度的推荐高度

代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 创建 Gallery Group 并设置样式
SARibbonGalleryGroup* group = gallery->addCategoryActions(tr("样式"), actions);
group->setGalleryGroupStyle(SARibbonGalleryGroup::IconWithWordWrapText);
group->setDisplayRow(SARibbonGalleryGroup::DisplayTwoRow);
group->setGridMinimumWidth(80);
group->setGridMaximumWidth(120);

// 响应触发信号
connect(group, &SARibbonGalleryGroup::triggered, this, [](QAction* act) {
    qDebug() << "Selected:" << act->text();
});

// 监听悬停信号(需启用鼠标跟踪)
group->setMouseTracking(true);
connect(group, &SARibbonGalleryGroup::hovered, this, [](QAction* act) {
    qDebug() << "Hovered:" << act->text();
});

SARibbonGalleryItem 用法

SARibbonGalleryItem 是 Gallery 中的单个数据项,类似 QStandardItem,用于设置图标、文字、关联动作等数据。

API摘要

方法名 返回值 说明
SARibbonGalleryItem() 构造 创建空项
SARibbonGalleryItem(const QString&, const QIcon&) 构造 创建带文字和图标的项
SARibbonGalleryItem(QAction*) 构造 从 QAction 创建
setText(const QString&) void 设置文字
text() QString 获取文字
setToolTip(const QString&) void 设置工具提示
toolTip() QString 获取工具提示
setIcon(const QIcon&) void 设置图标
icon() QIcon 获取图标
setAction(QAction*) void 设置关联的动作
action() QAction* 获取关联的动作
setSelectable(bool) void 设置是否可选中
isSelectable() bool 是否可选中
setEnable(bool) void 设置是否可用
isEnable() bool 是否可用
setTextAlignment(Qt::Alignment) void 设置文字对齐方式
textAlignment() Qt::Alignment 获取文字对齐方式
setData(int role, const QVariant&) void 设置指定角色的数据
data(int role) QVariant 获取指定角色的数据

代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 方式一:直接构造
SARibbonGalleryItem* item1 = new SARibbonGalleryItem(
    tr("标题样式1"), QIcon(":/icons/style1.svg"));
item1->setToolTip(tr("应用标题样式1"));
group->addItem(item1);

// 方式二:从 QAction 创建
QAction* act = new QAction(QIcon(":/icons/style2.svg"), tr("样式2"), this);
SARibbonGalleryItem* item2 = new SARibbonGalleryItem(act);
item2->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
group->addItem(item2);

// 方式三:创建后设置数据
SARibbonGalleryItem* item3 = new SARibbonGalleryItem();
item3->setText(tr("自定义样式"));
item3->setIcon(QIcon(":/icons/style3.svg"));
item3->setToolTip(tr("应用自定义标题样式"));
item3->setSelectable(true);
group->addItem(item3);

SARibbonGalleryViewport 详解

SARibbonGalleryViewportSARibbonGallery 弹出时显示所有 GalleryGroup 的视口窗口,继承自 QScrollArea。内部使用垂直布局管理多个 GalleryGroup。

API摘要

方法名 返回值 说明
addWidget(QWidget*) void 添加控件(不带标题)
addWidget(QWidget*, const QString&) void 添加控件并设置标题
titleLabel(QWidget*) QLabel* 获取控件对应的标题标签
removeWidget(QWidget*) void 移除控件
galleryGroupList() QList<SARibbonGalleryGroup*> 获取所有 GalleryGroup
galleryHeight() int 获取 Gallery 高度
heightHintForWidth(int) int 根据宽度获取推荐高度

代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// 获取 Viewport 并自定义
SARibbonGalleryViewport* viewport = gallery->getPopupViewPort();
if (viewport) {
    // 修改某个 GalleryGroup 的标题样式
    QLabel* title = viewport->titleLabel(group1);
    if (title) {
        title->setStyleSheet("font-size: 14px; font-weight: bold; color: #333;");
    }

    // 添加自定义控件到 Viewport
    QWidget* customWidget = new QWidget(viewport);
    viewport->addWidget(customWidget, tr("自定义区域"));

    // 移除不需要的控件
    // viewport->removeWidget(someWidget);
}

// 响应展开按钮显示更多
connect(gallery, &SARibbonGallery::triggered, this, [](QAction* act) {
    qDebug() << "Gallery item triggered:" << act->text();
});

SARibbonSystemButtonBar 详细方法

SARibbonSystemButtonBar 是窗口标题栏右侧的系统按钮栏,包含最小化、最大化、关闭按钮,并支持添加自定义按钮和控件。

API摘要

方法名 返回值 说明
addAction(QAction*) void 添加动作按钮
addMenuAction(QAction*, popupMode) void 添加菜单动作
addMenuAction(QMenu*, popupMode) QAction* 添加菜单并返回菜单动作
addSeparator() QAction* 添加分隔线
addWidget(QWidget*) QAction* 添加自定义控件
setupMinimizeButton(bool) void 设置最小化按钮显隐
setupMaximizeButton(bool) void 设置最大化按钮显隐
setupCloseButton(bool) void 设置关闭按钮显隐
setButtonWidthStretch(close, max, min) void 设置按钮宽度比例
setWindowTitleHeight(int) void 设置标题栏高度
windowTitleHeight() int 获取标题栏高度
setWindowButtonWidth(int) void 设置系统按钮宽度
windowButtonWidth() int 获取系统按钮宽度
setWindowStates(Qt::WindowStates) void 设置窗口状态
windowButtonFlags() Qt::WindowFlags 获取按钮标志
minimizeButton() QAbstractButton* 获取最小化按钮
maximizeButton() QAbstractButton* 获取最大化按钮
closeButton() QAbstractButton* 获取关闭按钮
setIconSize(const QSize&) void 设置图标尺寸
iconSize() QSize 获取图标尺寸
updateWindowFlag() void 更新窗口标志

代码示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void MainWindow::setupSystemButtonBar()
{
    SARibbonSystemButtonBar* sysBar = windowButtonBar();
    if (!sysBar) {
        return;
    }

    // 自定义按钮宽度比例
    sysBar->setButtonWidthStretch(4, 3, 3);

    // 添加分隔线
    sysBar->addSeparator();

    // 添加登录按钮
    QAction* loginAction = new QAction(QIcon(":/icon/login.svg"), tr("登录"), this);
    sysBar->addAction(loginAction);
    connect(loginAction, &QAction::triggered, this, &MainWindow::onLogin);

    // 添加带菜单的下拉按钮
    QMenu* themeMenu = new QMenu(tr("主题"), this);
    themeMenu->addAction(tr("浅色"));
    themeMenu->addAction(tr("深色"));
    sysBar->addMenuAction(themeMenu, QToolButton::MenuButtonPopup);

    // 添加自定义控件
    QLabel* statusLabel = new QLabel(tr("在线"), sysBar);
    statusLabel->setStyleSheet("color: green; padding: 0 4px;");
    sysBar->addWidget(statusLabel);

    // 自定义系统按钮图标和尺寸
    sysBar->setIconSize(QSize(16, 16));
}