目录
一、Ribbon是什么?
二、优秀的QT开源项目-SARibbon
1.项目链接
2.编译方法
三、使用方法
1.简单的层次示意
2. 拆分下的SARibbonBar层级关系
四、模仿搭建一个ArcGis_pro界面
1.创建Category和Pannel:
2.QAction 加入菜单
3.添加Gallery 预览控件
五、总结
前言
office式界面就是传说中的ribbon模式了,就是我们经常看到的word模式,office模式的tab和标题栏占用位置较多的一种界面模式。
如:word界面
WPS Ribbon 样式
Ribbon是现代化的方式帮助用户高效和直接的查找、理解和使用工具命令——通过最少的点击,减少从“尝试-错误”(trainl-and-error)方式中恢复操作,寻找新的操作的需要,并且不再需要区查看软件帮助。
Ribbon是一种命令工具条(command bar),将软件的功能集成到窗口上方的一系列标签(tabs)中。使用Ribbon可以使得软件的功能和特性更容易被用户发现,加快软件整体学习的速度,使用户能够根据他们自身的经验更好的控制整个程序。Ribbon可以代替传统的菜单栏和工具栏。
简单的理解,Ribbon是把菜单栏和工具栏合并了,并通过一个tab控件进行展示。
SARibbonBar
是Qt的开源Ribbon控件,代码托管于github和gitee
SARibbon
介绍[github],[gitee]SARibbon
布局入门[github],[gitee]
使用Qt Creator直接打开SARibbon.pro,并编译即可,会编译出SARibbonBar库和一个(目前只有一个例子)例子,lib和例子的目录位于bin_qt{Qt版本}_{debug/release}_{32/64}目录下
在debug模式编译的库后面会加上d以作区别
可以把编译好的整个目录移动到需要的工程目录下,然后在项目的pro文件中,include SARibbonBar.pri即可,示例如下:
include($$PWD/SARibbonBar/SARibbon/SARibbonBar.pri)
要使用SARibbon,需要对QMainWindow替换为SARibbonMainWindow,SARibbonMainWindow修改了QMainWindow对menubar的渲染
示例代码如下:
#include "SARibbonMainWindow.h"
class MainWindow : public SARibbonMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget* par = nullptr);
...
}
Ribbon是把菜单栏和工具栏合并了,并通过一个tab控件进行展示,SARibbon
在设计时参考了MFC Ribbon接口的命名风格,标签页称之为Category
(种类),每个Category
下面有多个pannel
(面板),面板下面才是具体的toolbutton。
看到这里,我们对它的构造层级就有了一定的了解,接下来我们再具体了解其中的各个控件
Ribbon标签(tabs)有许多“组”(group)构成,这些组中一些密切相关的功能的集合。出了标签和组,ribbons还包括:
SARibbonCategory
SARibbonContextCategory
SARibbonApplicationButton
,可以隐藏SARibbonQuickAccessBar
SARibbonGallery
//添加主标签页 - 通过addCategoryPage工厂函数添加
SARibbonCategory* categoryMain = ribbon->addCategoryPage(tr("地图"));
//使用addPannel函数来创建SARibbonPannel,效果和new SARibbonPannel再addPannel一样
SARibbonPannel* pannelStyle = page->addPannel(("粘贴板"));
QAction* actstickup = createAction(tr("粘贴"), ":/icon/icon/EditPaste32.png");
pannelStyle->addLargeAction(actstickup);
connect(actstickup, &QAction::triggered, this, [ this ](bool b) {
Q_UNUSED(b);
this->m_edit->append("actstickup clicked");
});
/*
* 新增剪贴
* */
QAction* clip = createAction(tr("剪贴"), ":/icon/icon/EditCut32.png", "剪贴");
clip->setCheckable(true);
pannelStyle->addSmallAction(clip);
// 复制
QAction* actShowHideButton = createAction(tr("复制"), ":/icon/icon/EditCopy32.png", "复制");
actShowHideButton->setCheckable(true);
pannelStyle->addSmallAction(actShowHideButton);
connect(actShowHideButton, &QAction::triggered, this, [ this ](bool b) {
this->ribbonBar()->showMinimumModeButton(b); //显示ribbon最小化按钮
});
actShowHideButton->trigger();
//复制路径
QAction* Paste = createAction(tr("复制路径"), ":/icon/icon/EffectsLayerDepthPriority16.png");
Paste->setCheckable(true);
Paste->setToolTip("复制路径");
pannelStyle->addSmallAction(Paste);
connect(Paste, &QAction::triggered, this, &MainWindow::onActionwordWrapIn2rowTriggered);
查看效果:
通过addLargeAction
、addMediumAction
、addSmallAction
可以组合出不同的布局样式。
代码体现:
QAction* actstickup = createAction(tr("粘贴"), ":/icon/icon/EditPaste32.png");
pannelStyle->addLargeAction(actstickup);
QAction* clip = createAction(tr("剪贴"), ":/icon/icon/EditCut32.png", "剪贴");
clip->setCheckable(true);
pannelStyle->addSmallAction(clip);
在标准的pannel中,一个action(按钮)有3种布局,以office word为例,pannel的三种布局其实是所占行数:
large
medium
samll
因此,pannel的布局其实归根结底就是行数,可以理解为QGridLayout
来对pannel进行布局的,把grid分割为6行,large
模式下占全部6行,medium
模式下占据3行,small
模式下占据2行(实际并不是用GridLayout布置的)。
枚举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里的布局。
入浏览中添加:
"顶部图层" "可见图层 " "可选图层 " "内容中的可选内容 " "无弹出窗口 " "平面导航 " " 第一人称导航"
首先创建QAction 在创建menu 最后将menu设置到QAction中。代码如下:
SARibbonMenu *menuLook = new SARibbonMenu(this);
QList list;
list<<"顶部图层"<<"可见图层 "<<"可选图层 "<<"内容中的可选内容 "<<"无弹出窗口 "<<"平面导航 "<< " 第一人称导航";
QAction* look = nullptr;
{
QIcon itemicon = QIcon(":/icon/icon/item.svg");
for (int i =0;iaddAction(itemicon, tr("%1").arg(list[i]));
look->setObjectName(QStringLiteral("item %1").arg(i+1));
}
}
QAction* act = createAction(tr("浏览"), ":/icon/icon/3DNavigationTool32.png");
act->setMenu(menuLook);
btn = pannelToolButtonStyle->addLargeAction(act);
btn->setPopupMode(QToolButton::InstantPopup);
connect(act, &QAction::triggered, this, &MainWindow::onDelayedPopupCheckabletriggered);
查看效果:
我们可见其中menu 的图标都一样,不好区分,如果有朋友喜欢在做精致一点可以这样给每一个都加上不同的图标:或者加入分割符。
代码如下
QAction* Newreport = nullptr;
{
QList itemicon;
//加入图标
itemicon<addAction(itemicon[i], tr("%1").arg(listNewreport[i]));
//在第一行和第二行加一行分隔符。
if(i == 1)
{
menuConnection->addSeparator();
}
Newreport->setObjectName(QStringLiteral("item %1").arg(i+1));
}
}
Gallery 预览控件,这是Ribbon最吸引眼球的控件,用直观的图像把功能显示出来,甚至有些会根据上下文进行实时渲染,典型的就是word开始标签下的样式选择,对应SARibbonGallery
对应代码设计:
SARibbonPannel* pannelLayerTemplates = page->addPannel(tr("图层模板"));
SARibbonGallery* gallery = pannelLayerTemplates->addGallery();
QList< QAction* > galleryActions;
auto lambdaCreateGalleryAction = [ this ](const QString& text, const QString& iconurl) -> QAction* {
QAction* act = this->createAction(text, iconurl);
this->connect(act, &QAction::triggered, this, [ this, text ]() {
if (this->m_edit) {
this->m_edit->append(QString("%1 triggered").arg(text));
}
});
return act;
};
galleryActions.append(lambdaCreateGalleryAction("亮色地图注释", ":/gallery-icon/icon/gallery/Document-File.svg"));
galleryActions.append(lambdaCreateGalleryAction("深色地图注释", ":/gallery-icon/icon/gallery/Download-File.svg"));
galleryActions.append(lambdaCreateGalleryAction("浅色地图注释", ":/gallery-icon/icon/gallery/Drive-File.svg"));
galleryActions.append(lambdaCreateGalleryAction("配对地图注释", ":/gallery-icon/icon/gallery/Dropbox-File.svg"));
galleryActions.append(lambdaCreateGalleryAction("粉彩地图注释", ":/gallery-icon/icon/gallery/Email-File.svg"));
galleryActions.append(lambdaCreateGalleryAction("红绿地图注释", ":/gallery-icon/icon/gallery/Encode-File.svg"));
效果如下;
总之 SARibbon是一个非常优秀的开源项目,更多更详细的例子参考项目官方文档:GitHub - czyt1988/SARibbon: Ribbon Control for Qt
本人也在学习中,如有错误欢迎指正。感谢您的阅读