├── pyqt ├── .gitignore ├── demo │ └── res │ │ ├── logo.png │ │ ├── setText.svg │ │ ├── Italic.svg │ │ ├── Underline.svg │ │ ├── smallFont.svg │ │ ├── action2.svg │ │ ├── disable.svg │ │ ├── action3.svg │ │ ├── action4.svg │ │ ├── al-bothside.svg │ │ ├── al-left.svg │ │ ├── al-center.svg │ │ ├── al-right.svg │ │ ├── largerFont.svg │ │ ├── showHideButton.svg │ │ ├── file.svg │ │ ├── remove.svg │ │ ├── windowsflag-normal.svg │ │ ├── wordwrap.svg │ │ ├── removePage.svg │ │ ├── help.svg │ │ ├── folder-stats.svg │ │ ├── show.svg │ │ ├── showContext.svg │ │ ├── folder-table.svg │ │ ├── folder-checkmark.svg │ │ ├── undo.svg │ │ ├── redo.svg │ │ ├── folder-star.svg │ │ ├── delete.svg │ │ ├── deleteContext.svg │ │ ├── useqss.svg │ │ ├── useCustomize.svg │ │ ├── item.svg │ │ ├── bold.svg │ │ ├── hideRibbon.svg │ │ ├── long-text.svg │ │ ├── remove-app-btn.svg │ │ ├── enableTest.svg │ │ ├── gallery │ │ ├── Adobe.svg │ │ ├── File-Readonly.svg │ │ ├── Illustrator.svg │ │ ├── File-Error.svg │ │ ├── Download-File.svg │ │ ├── Drive-File.svg │ │ ├── Document-File.svg │ │ ├── Favorit-File.svg │ │ └── Photoshop.svg │ │ ├── save.svg │ │ ├── Align-Left.svg │ │ ├── Align-Right.svg │ │ ├── Align-Center.svg │ │ ├── unlock.svg │ │ ├── ContextPage.svg │ │ ├── folder-cog.svg │ │ ├── Decrease-Indent.svg │ │ └── Decrease-Margin.svg ├── test │ ├── res │ │ └── logo.png │ ├── test_RibbonBar.py │ └── test_RibbonGallery.py ├── PyRibbon │ ├── res │ │ ├── logo.png │ │ ├── ArrowUp.png │ │ ├── ArrowDown.png │ │ ├── ArrowMore.png │ │ ├── Titlebar_Max.png │ │ ├── Titlebar_Min.png │ │ ├── Titlebar_Close.png │ │ ├── Titlebar_Normal.png │ │ ├── Titlebar_Shade.png │ │ ├── Titlebar_Unshade.png │ │ ├── Titlebar_Close_Hover.png │ │ └── ribbonGroupOptionButton.png │ ├── QxRibbon.py │ ├── QxRibbonTabBar.py │ ├── QxRibbonApplicationButton.py │ ├── QxRibbonRes.qrc │ ├── __init__.py │ ├── QxRibbonQuickAccessBar.py │ └── QxRibbonContainers.py └── LICENSE ├── demo ├── demo.rc ├── logo.ico ├── aboutdialog.h ├── res │ ├── setText.svg │ ├── logo.svg │ ├── italic.svg │ ├── smallFont.svg │ ├── theme.svg │ ├── action2.svg │ ├── disable.svg │ ├── action3.svg │ ├── action4.svg │ ├── copy.svg │ ├── align-bothside.svg │ ├── align-left.svg │ ├── align-right.svg │ ├── align-center.svg │ ├── largerFont.svg │ ├── undo.svg │ ├── redo.svg │ ├── remove.svg │ ├── folder.svg │ ├── windowsflag-normal.svg │ ├── wordwrap.svg │ ├── removePage.svg │ ├── folder-stats.svg │ ├── folder-table.svg │ ├── folder-checkmark.svg │ ├── folder-add.svg │ ├── folder-star.svg │ ├── delete.svg │ ├── deleteContext.svg │ ├── useqss.svg │ ├── help.svg │ ├── useCustomize.svg │ ├── bold.svg │ ├── long-text.svg │ ├── remove-app-btn.svg │ ├── enableTest.svg │ ├── show.svg │ ├── gallery │ │ ├── Adobe.svg │ │ ├── File-Readonly.svg │ │ ├── Illustrator.svg │ │ ├── File-Error.svg │ │ ├── Download-File.svg │ │ ├── Drive-File.svg │ │ ├── Document-File.svg │ │ ├── Favorit-File.svg │ │ └── Photoshop.svg │ ├── unlock.svg │ ├── hideRibbon.svg │ ├── logo64.svg │ ├── showContext.svg │ ├── folder-cog.svg │ └── clipboard.svg ├── editablecontainer.h ├── editablecontainer.cpp ├── demo.pro ├── CMakeLists.txt └── main.cpp ├── doc └── images │ ├── qt.png │ ├── logo.png │ ├── mainwindow.png │ ├── mainwindow_dark.png │ ├── mainwindow_pyqt.png │ ├── mainwindow_linux.png │ ├── mainwindow_normal.png │ ├── mainwindow_ubuntu.png │ └── mainwindow_ubuntu_normal.png ├── projects ├── template │ ├── src │ │ ├── libs │ │ │ ├── qxribbon │ │ │ │ ├── qxribbon_dependencies.pri │ │ │ │ └── qxribbon.pro │ │ │ └── libs.pro │ │ ├── app │ │ │ ├── res │ │ │ │ └── image │ │ │ │ │ └── logo.png │ │ │ ├── app.qrc │ │ │ ├── main.cpp │ │ │ ├── mainwindow.h │ │ │ ├── mainwindow.cpp │ │ │ └── app.pro │ │ ├── src.pro │ │ └── qtlibrary.pri │ ├── qtproject.pri │ ├── template.pro │ └── config.pri └── README.md ├── src ├── res │ ├── ArrowUp.png │ ├── ArrowDown.png │ ├── ArrowMore.png │ ├── Titlebar_Max.png │ ├── Titlebar_Min.png │ ├── Titlebar_Close.png │ ├── Titlebar_Normal.png │ ├── Titlebar_Shade.png │ ├── Titlebar_Unshade.png │ ├── lighter │ │ ├── ArrowUp.png │ │ ├── ArrowDown.png │ │ ├── ArrowMore.png │ │ ├── Titlebar_Max.png │ │ ├── Titlebar_Min.png │ │ ├── Titlebar_Close.png │ │ ├── Titlebar_Normal.png │ │ ├── Titlebar_Shade.png │ │ ├── Titlebar_Unshade.png │ │ ├── Titlebar_Close_Hover.png │ │ └── ribbonGroupOptionButton.png │ ├── Titlebar_Close_Hover.png │ └── ribbonGroupOptionButton.png ├── src.pro ├── QxRibbonUtils.h ├── QxRibbonTabBar.cpp ├── QxRibbonTabBar.h ├── QxRibbonApplicationButton.h ├── QxRibbonColorButtonPrivate.h ├── QxRibbonFactory.h ├── QxRibbonApplicationButton.cpp ├── QxRibbonManager.cpp ├── QxRibbonTheme.h ├── QxRibbonManager.h ├── QxRibbonFactory.cpp ├── QxRibbonColorButton.h ├── QxRibbonUtils.cpp ├── QxRibbonQuickAccessBar.h ├── QxRibbonTheme.cpp ├── QxWindowButtonGroupPrivate.h ├── QxRibbonButtonGroup.h ├── QxRibbonStyleOption.h ├── QxRibbonPageContext.h ├── QxWindowButtonGroup.h ├── res.qrc ├── FramelessHelper.h ├── QxRibbonContainers.h ├── QxRibbonGroupPrivate.h ├── QxRibbonCustomizeDialog.h ├── QxRibbonButtonPrivate.h ├── QxRibbonControls.h └── QxRibbonButton.h ├── QxRibbon.pro ├── common.pri ├── CMakeLists.txt ├── .gitignore └── LICENSE /pyqt/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.idea -------------------------------------------------------------------------------- /demo/demo.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON "logo.ico" -------------------------------------------------------------------------------- /demo/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/demo/logo.ico -------------------------------------------------------------------------------- /doc/images/qt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/doc/images/qt.png -------------------------------------------------------------------------------- /doc/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/doc/images/logo.png -------------------------------------------------------------------------------- /projects/template/src/libs/qxribbon/qxribbon_dependencies.pri: -------------------------------------------------------------------------------- 1 | QTC_LIB_NAME = QxRibbon 2 | -------------------------------------------------------------------------------- /src/res/ArrowUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/ArrowUp.png -------------------------------------------------------------------------------- /pyqt/demo/res/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/demo/res/logo.png -------------------------------------------------------------------------------- /pyqt/test/res/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/test/res/logo.png -------------------------------------------------------------------------------- /src/res/ArrowDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/ArrowDown.png -------------------------------------------------------------------------------- /src/res/ArrowMore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/ArrowMore.png -------------------------------------------------------------------------------- /doc/images/mainwindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/doc/images/mainwindow.png -------------------------------------------------------------------------------- /projects/template/qtproject.pri: -------------------------------------------------------------------------------- 1 | include(config.pri) 2 | include($$QTCANPOOL_DIR/qtproject.pri) 3 | -------------------------------------------------------------------------------- /src/res/Titlebar_Max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/Titlebar_Max.png -------------------------------------------------------------------------------- /src/res/Titlebar_Min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/Titlebar_Min.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/logo.png -------------------------------------------------------------------------------- /src/res/Titlebar_Close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/Titlebar_Close.png -------------------------------------------------------------------------------- /src/res/Titlebar_Normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/Titlebar_Normal.png -------------------------------------------------------------------------------- /src/res/Titlebar_Shade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/Titlebar_Shade.png -------------------------------------------------------------------------------- /src/res/Titlebar_Unshade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/Titlebar_Unshade.png -------------------------------------------------------------------------------- /src/res/lighter/ArrowUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/ArrowUp.png -------------------------------------------------------------------------------- /doc/images/mainwindow_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/doc/images/mainwindow_dark.png -------------------------------------------------------------------------------- /doc/images/mainwindow_pyqt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/doc/images/mainwindow_pyqt.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/ArrowUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/ArrowUp.png -------------------------------------------------------------------------------- /src/res/lighter/ArrowDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/ArrowDown.png -------------------------------------------------------------------------------- /src/res/lighter/ArrowMore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/ArrowMore.png -------------------------------------------------------------------------------- /doc/images/mainwindow_linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/doc/images/mainwindow_linux.png -------------------------------------------------------------------------------- /doc/images/mainwindow_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/doc/images/mainwindow_normal.png -------------------------------------------------------------------------------- /doc/images/mainwindow_ubuntu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/doc/images/mainwindow_ubuntu.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/ArrowDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/ArrowDown.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/ArrowMore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/ArrowMore.png -------------------------------------------------------------------------------- /src/res/Titlebar_Close_Hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/Titlebar_Close_Hover.png -------------------------------------------------------------------------------- /src/res/lighter/Titlebar_Max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/Titlebar_Max.png -------------------------------------------------------------------------------- /src/res/lighter/Titlebar_Min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/Titlebar_Min.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/Titlebar_Max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/Titlebar_Max.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/Titlebar_Min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/Titlebar_Min.png -------------------------------------------------------------------------------- /src/res/lighter/Titlebar_Close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/Titlebar_Close.png -------------------------------------------------------------------------------- /src/res/lighter/Titlebar_Normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/Titlebar_Normal.png -------------------------------------------------------------------------------- /src/res/lighter/Titlebar_Shade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/Titlebar_Shade.png -------------------------------------------------------------------------------- /src/res/ribbonGroupOptionButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/ribbonGroupOptionButton.png -------------------------------------------------------------------------------- /projects/template/src/libs/qxribbon/qxribbon.pro: -------------------------------------------------------------------------------- 1 | include(../../qtlibrary.pri) 2 | include($$QXRIBBON_DIR/src/QxRibbon.pri) 3 | -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/Titlebar_Close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/Titlebar_Close.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/Titlebar_Normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/Titlebar_Normal.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/Titlebar_Shade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/Titlebar_Shade.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/Titlebar_Unshade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/Titlebar_Unshade.png -------------------------------------------------------------------------------- /src/res/lighter/Titlebar_Unshade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/Titlebar_Unshade.png -------------------------------------------------------------------------------- /QxRibbon.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | CONFIG += ordered 3 | 4 | SUBDIRS = \ 5 | src \ 6 | demo 7 | 8 | demo.depends = src 9 | -------------------------------------------------------------------------------- /doc/images/mainwindow_ubuntu_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/doc/images/mainwindow_ubuntu_normal.png -------------------------------------------------------------------------------- /src/res/lighter/Titlebar_Close_Hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/Titlebar_Close_Hover.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/Titlebar_Close_Hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/Titlebar_Close_Hover.png -------------------------------------------------------------------------------- /src/res/lighter/ribbonGroupOptionButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/src/res/lighter/ribbonGroupOptionButton.png -------------------------------------------------------------------------------- /projects/template/src/app/res/image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/projects/template/src/app/res/image/logo.png -------------------------------------------------------------------------------- /pyqt/PyRibbon/res/ribbonGroupOptionButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/canpool/QxRibbon/HEAD/pyqt/PyRibbon/res/ribbonGroupOptionButton.png -------------------------------------------------------------------------------- /projects/template/src/app/app.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | res/image/logo.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /projects/template/src/src.pro: -------------------------------------------------------------------------------- 1 | include(../qtproject.pri) 2 | 3 | TEMPLATE = subdirs 4 | CONFIG += ordered 5 | 6 | SUBDIRS += \ 7 | libs \ 8 | app 9 | 10 | -------------------------------------------------------------------------------- /projects/template/src/qtlibrary.pri: -------------------------------------------------------------------------------- 1 | isEmpty(QTLIBRARY_PRO_FILE_PWD): QTLIBRARY_PRO_FILE_PWD = $$_PRO_FILE_PWD_ 2 | 3 | include(../config.pri) 4 | include($$QTCANPOOL_DIR/src/qtlibrary.pri) 5 | -------------------------------------------------------------------------------- /common.pri: -------------------------------------------------------------------------------- 1 | 2 | # eg: $$qtLibraryNameVersion(qcanpool, 1) 3 | defineReplace(qtLibraryNameVersion) { 4 | RET = $$qtLibraryTarget($$1) 5 | win32 { 6 | RET = $$RET$$2 7 | } 8 | return($$RET) 9 | } 10 | 11 | INCLUDEPATH += $$PWD/src 12 | -------------------------------------------------------------------------------- /src/src.pro: -------------------------------------------------------------------------------- 1 | lessThan(QT_MAJOR_VERSION, 5) { 2 | error("don't support qt $${QT_VERSION}") 3 | } 4 | 5 | OUT_ROOT = $${OUT_PWD}/.. 6 | TARGET = $$qtLibraryTarget(QxRibbon) 7 | TEMPLATE = lib 8 | DESTDIR = $${OUT_ROOT}/bin 9 | 10 | include($$PWD/QxRibbon.pri) 11 | -------------------------------------------------------------------------------- /projects/template/src/app/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | 8 | MainWindow w; 9 | w.show(); 10 | 11 | return a.exec(); 12 | } 13 | -------------------------------------------------------------------------------- /projects/template/template.pro: -------------------------------------------------------------------------------- 1 | include(qtproject.pri) 2 | 3 | !minQtVersion(5, 0, 0) { 4 | message("Cannot build Qt Canpool with Qt version $${QT_VERSION}.") 5 | error("Can only use Qt 5.") 6 | } 7 | 8 | TEMPLATE = subdirs 9 | CONFIG += ordered 10 | 11 | SUBDIRS += src \ 12 | 13 | 14 | -------------------------------------------------------------------------------- /projects/template/src/libs/libs.pro: -------------------------------------------------------------------------------- 1 | include(../../qtproject.pri) 2 | 3 | TEMPLATE = subdirs 4 | 5 | SUBDIRS = \ 6 | qxribbon 7 | 8 | for(l, SUBDIRS) { 9 | QTC_LIB_DEPENDS = 10 | include($$l/$${l}_dependencies.pri) 11 | lv = $${l}.depends 12 | $$lv = $$QTC_LIB_DEPENDS 13 | } 14 | -------------------------------------------------------------------------------- /projects/template/src/app/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include "QxRibbonWindow.h" 5 | 6 | class MainWindow : public RibbonWindow 7 | { 8 | Q_OBJECT 9 | 10 | public: 11 | MainWindow(QWidget *parent = nullptr); 12 | ~MainWindow(); 13 | }; 14 | 15 | #endif // MAINWINDOW_H 16 | -------------------------------------------------------------------------------- /pyqt/PyRibbon/QxRibbon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2023 maminjie 3 | # SPDX-License-Identifier: GPL-3.0 4 | 5 | QX_RIBBON_VERSION_STR = "0.1.0" 6 | 7 | 8 | class Ribbon: 9 | """Microsoft Ribbon for PyQt""" 10 | @staticmethod 11 | def version() -> str: 12 | return QX_RIBBON_VERSION_STR 13 | -------------------------------------------------------------------------------- /projects/template/src/app/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | MainWindow::MainWindow(QWidget *parent) 4 | : RibbonWindow(parent) 5 | { 6 | setWindowIcon(QIcon(":/res/image/logo.png")); 7 | setWindowTitle(tr("QxRibbon Library Template")); 8 | 9 | resize(400, 200); 10 | } 11 | 12 | MainWindow::~MainWindow() 13 | { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/QxRibbonUtils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023-2024 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | 10 | namespace QxRibbon { 11 | 12 | /* color */ 13 | QX_RIBBON_EXPORT QIcon colorIcon(const QColor &color, const QSize &size); 14 | 15 | } // namespace QxRibbon 16 | -------------------------------------------------------------------------------- /demo/aboutdialog.h: -------------------------------------------------------------------------------- 1 | #ifndef ABOUTDIALOG_H 2 | #define ABOUTDIALOG_H 3 | 4 | #include 5 | 6 | class AboutDialog : public QDialog 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit AboutDialog(const QString &softlogo, const QString &softname, const QString &softver, 11 | const QString &softdesc, QWidget *parent = nullptr); 12 | virtual ~AboutDialog(); 13 | }; 14 | 15 | #endif // ABOUTDIALOG_H 16 | -------------------------------------------------------------------------------- /projects/README.md: -------------------------------------------------------------------------------- 1 | ## 模板说明 2 | 3 | ### template 4 | - 采用 app + lib 模式 5 | 6 | ## 依赖 7 | 8 | ### qtcanpool 9 | 10 | 模板采用了 [qtcanpool](https://gitee.com/icanpool/qtcanpool) 工程模板,所以需要依赖 qtcanpool 的工程管理。 11 | 12 | 通过在模板目录下的 config.pri 文件中配置 QTCANPOOL_DIR 变量来关联 qtcanpool 工程,如: 13 | ``` 14 | isEmpty(QTCANPOOL_DIR): QTCANPOOL_DIR = $$quote(D:\projects\qt\qtcanpool) 15 | ``` 16 | 此处说明 qtcanpool 工程放在 D 盘的 projects\qt 目录中。 17 | 18 | 备注:推荐使用 qtcanpool 的 master 分支。 19 | -------------------------------------------------------------------------------- /demo/res/setText.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/setText.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/editablecontainer.h: -------------------------------------------------------------------------------- 1 | #ifndef EDITABLECONTAINER_H 2 | #define EDITABLECONTAINER_H 3 | 4 | #include 5 | 6 | class EditableContainer : public QWidget 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit EditableContainer(QWidget *parent = nullptr); 11 | virtual ~EditableContainer(); 12 | 13 | void setWidget(QWidget *widget); 14 | void setContentsMargins(int left, int top, int right, int bottom); 15 | 16 | private: 17 | QWidget *m_widget; 18 | }; 19 | 20 | #endif // EDITABLECONTAINER_H 21 | -------------------------------------------------------------------------------- /src/QxRibbonTabBar.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #include "QxRibbonTabBar.h" 6 | 7 | RibbonTabBar::RibbonTabBar(QWidget *parent) 8 | : QTabBar(parent) 9 | , m_tabMargin(6, 0, 0, 0) 10 | { 11 | setExpanding(false); 12 | } 13 | 14 | const QMargins &RibbonTabBar::tabMargin() const 15 | { 16 | return m_tabMargin; 17 | } 18 | 19 | void RibbonTabBar::setTabMargin(const QMargins &margin) 20 | { 21 | m_tabMargin = margin; 22 | } 23 | -------------------------------------------------------------------------------- /demo/res/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonTabBar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | #include 10 | 11 | class QX_RIBBON_EXPORT RibbonTabBar : public QTabBar 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit RibbonTabBar(QWidget *parent = Q_NULLPTR); 16 | 17 | const QMargins &tabMargin() const; 18 | void setTabMargin(const QMargins &margin); 19 | private: 20 | QMargins m_tabMargin; 21 | }; 22 | -------------------------------------------------------------------------------- /demo/res/italic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/Italic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/Underline.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/smallFont.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/theme.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonApplicationButton.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | 10 | class QX_RIBBON_EXPORT RibbonApplicationButton : public QPushButton 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit RibbonApplicationButton(QWidget *parent = Q_NULLPTR); 15 | explicit RibbonApplicationButton(const QString &text, QWidget *parent = Q_NULLPTR); 16 | RibbonApplicationButton(const QIcon &icon, const QString &text, QWidget *parent = Q_NULLPTR); 17 | }; 18 | -------------------------------------------------------------------------------- /pyqt/demo/res/smallFont.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/action2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/PyRibbon/QxRibbonTabBar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2023 maminjie 3 | # SPDX-License-Identifier: GPL-3.0 4 | 5 | from PyQt5.QtCore import QMargins 6 | from PyQt5.QtWidgets import QTabBar 7 | 8 | 9 | class RibbonTabBar(QTabBar): 10 | 11 | def __init__(self, parent): 12 | super().__init__(parent) 13 | self.m_tabMargin: QMargins = QMargins(6, 0, 0, 0) 14 | self.setExpanding(False) 15 | 16 | def tabMargin(self) -> QMargins: 17 | return self.m_tabMargin 18 | 19 | def setTabMargin(self, margin: QMargins): 20 | self.m_tabMargin = margin 21 | -------------------------------------------------------------------------------- /pyqt/demo/res/action2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/disable.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonColorButtonPrivate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonButtonPrivate.h" 8 | 9 | #include 10 | 11 | class RibbonColorButton; 12 | 13 | class RibbonColorButtonPrivate : public RibbonButtonPrivate 14 | { 15 | public: 16 | Q_DECLARE_PUBLIC(RibbonColorButton) 17 | public: 18 | RibbonColorButtonPrivate(); 19 | 20 | QPixmap createIconPixmap(const QStyleOptionToolButton &opt, const QSize &iconsize) Q_DECL_OVERRIDE; 21 | public: 22 | QColor m_color; 23 | }; 24 | -------------------------------------------------------------------------------- /demo/res/action3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/action4.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/copy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/disable.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/align-bothside.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/action3.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/action4.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/align-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/align-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/al-bothside.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/al-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/align-center.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/al-center.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/al-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/largerFont.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/largerFont.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonFactory.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include "QxRibbonStyleOption.h" 9 | 10 | #include 11 | 12 | class RibbonControlButton; 13 | 14 | class QX_RIBBON_EXPORT RibbonFactory 15 | { 16 | public: 17 | RibbonFactory(); 18 | virtual ~RibbonFactory(); 19 | 20 | virtual RibbonControlButton *createHideGroupButton(QWidget *parent); 21 | 22 | RibbonStyleOption &getRibbonStyleOption(); 23 | void setRibbonStyleOption(RibbonStyleOption *opt); 24 | 25 | private: 26 | QScopedPointer m_opt; 27 | }; 28 | -------------------------------------------------------------------------------- /pyqt/PyRibbon/QxRibbonApplicationButton.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2023 maminjie 3 | # SPDX-License-Identifier: GPL-3.0 4 | 5 | from PyQt5.QtCore import Qt 6 | from PyQt5.QtWidgets import QPushButton 7 | 8 | 9 | class RibbonApplicationButton(QPushButton): 10 | 11 | def __init__(self, *args): 12 | """ 13 | RibbonApplicationButton(parent=None) 14 | RibbonApplicationButton(text: str, parent=None) 15 | RibbonApplicationButton(icon: QIcon, text: str, parent=None) 16 | """ 17 | super().__init__(*args) 18 | self.setFocusPolicy(Qt.NoFocus) 19 | self.setFlat(True) 20 | self.setMinimumWidth(40) 21 | -------------------------------------------------------------------------------- /pyqt/demo/res/showHideButton.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/PyRibbon/QxRibbonRes.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | res/ribbonGroupOptionButton.png 4 | res/ArrowDown.png 5 | res/ArrowMore.png 6 | res/ArrowUp.png 7 | res/Titlebar_Close.png 8 | res/Titlebar_Close_Hover.png 9 | res/Titlebar_Max.png 10 | res/Titlebar_Min.png 11 | res/Titlebar_Normal.png 12 | res/Titlebar_Shade.png 13 | res/Titlebar_Unshade.png 14 | 15 | 16 | res/default.qss 17 | res/office2013.qss 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/QxRibbonApplicationButton.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #include "QxRibbonApplicationButton.h" 6 | 7 | RibbonApplicationButton::RibbonApplicationButton(QWidget *parent) 8 | : RibbonApplicationButton(QIcon(), QString(), parent) 9 | { 10 | } 11 | 12 | RibbonApplicationButton::RibbonApplicationButton(const QString &text, QWidget *parent) 13 | : RibbonApplicationButton(QIcon(), text, parent) 14 | { 15 | } 16 | 17 | RibbonApplicationButton::RibbonApplicationButton(const QIcon &icon, const QString &text, QWidget *parent) 18 | : QPushButton(icon, text, parent) 19 | { 20 | setFocusPolicy(Qt::NoFocus); 21 | setFlat(true); 22 | setMinimumWidth(40); 23 | } 24 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | set(QX_RIBBON_VERSION_MAJOR 0) 4 | set(QX_RIBBON_VERSION_MINOR 5) 5 | set(QX_RIBBON_VERSION_PATCH 8) 6 | set(QX_RIBBON_VERSION "${QX_RIBBON_VERSION_MAJOR}.${QX_RIBBON_VERSION_MINOR}.${QX_RIBBON_VERSION_PATCH}") 7 | 8 | project(QtRibbon LANGUAGES CXX) 9 | 10 | option(BUILD_EXAMPLES "build the examples" ON) 11 | 12 | set(CMAKE_CXX_STANDARD 11) 13 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 14 | 15 | 16 | if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") 17 | set(QX_RIBBON_PLATFORM "x86") 18 | else() 19 | set(QX_RIBBON_PLATFORM "x64") 20 | endif() 21 | 22 | set(QX_RIBBON_BIN_DIR "${CMAKE_BINARY_DIR}/${QX_RIBBON_PLATFORM}") 23 | 24 | add_subdirectory(src) 25 | 26 | if(BUILD_EXAMPLES) 27 | add_subdirectory(demo) 28 | endif() 29 | -------------------------------------------------------------------------------- /demo/res/undo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/redo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonManager.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #include "QxRibbonManager.h" 6 | 7 | RibbonManager::RibbonManager() 8 | : m_factory(new RibbonFactory()) 9 | { 10 | } 11 | 12 | RibbonManager::~RibbonManager() 13 | { 14 | if (m_factory) { 15 | delete m_factory; 16 | } 17 | m_factory = Q_NULLPTR; 18 | } 19 | 20 | RibbonManager *RibbonManager::instance() 21 | { 22 | static RibbonManager s_instance; 23 | 24 | return &s_instance; 25 | } 26 | 27 | RibbonFactory *RibbonManager::factory() 28 | { 29 | return m_factory; 30 | } 31 | 32 | void RibbonManager::setupFactory(RibbonFactory *factory) 33 | { 34 | if (m_factory) { 35 | delete m_factory; 36 | } 37 | m_factory = factory; 38 | } 39 | -------------------------------------------------------------------------------- /demo/res/remove.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/remove.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/test/test_RibbonBar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2023 maminjie 3 | # SPDX-License-Identifier: GPL-3.0 4 | 5 | from PyQt5.QtWidgets import QApplication, QMainWindow 6 | 7 | from PyRibbon.QxRibbonBar import RibbonBar 8 | 9 | if __name__ == '__main__': 10 | app = QApplication([]) 11 | 12 | mainWindow = QMainWindow() 13 | ribbonBar = RibbonBar(mainWindow) 14 | ribbonBar.setRibbonStyle(RibbonBar.WpsLiteStyle) 15 | 16 | mainWindow.setMenuWidget(ribbonBar) 17 | 18 | ribbonBar.setContentsMargins(0, 0, 0, 0) 19 | ribbonBar.applicationButton().setText("File") 20 | 21 | page = ribbonBar.addPage('Page1') 22 | page = ribbonBar.addPage('Page2') 23 | 24 | mainWindow.setMinimumWidth(500) 25 | mainWindow.show() 26 | app.exec() 27 | -------------------------------------------------------------------------------- /demo/editablecontainer.cpp: -------------------------------------------------------------------------------- 1 | #include "editablecontainer.h" 2 | 3 | #include 4 | 5 | EditableContainer::EditableContainer(QWidget *parent) 6 | : QWidget(parent) 7 | , m_widget(Q_NULLPTR) 8 | { 9 | QHBoxLayout *lay = new QHBoxLayout(this); 10 | lay->setSpacing(0); 11 | lay->setContentsMargins(2, 0, 2, 0); 12 | } 13 | 14 | EditableContainer::~EditableContainer() 15 | { 16 | 17 | } 18 | 19 | void EditableContainer::setWidget(QWidget *widget) 20 | { 21 | if (m_widget) { 22 | layout()->removeWidget(m_widget); 23 | } 24 | m_widget = widget; 25 | layout()->addWidget(widget); 26 | } 27 | 28 | void EditableContainer::setContentsMargins(int left, int top, int right, int bottom) 29 | { 30 | layout()->setContentsMargins(left, top, right, bottom); 31 | } 32 | -------------------------------------------------------------------------------- /demo/res/folder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonTheme.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023-2024 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | 10 | class QWidget; 11 | 12 | class QX_RIBBON_EXPORT RibbonTheme : public QObject 13 | { 14 | Q_OBJECT 15 | public: 16 | enum ThemeStyle { 17 | NormalTheme, 18 | Office2013Theme, 19 | WpsdarkTheme, 20 | CustomTheme, 21 | }; 22 | Q_ENUM(ThemeStyle) 23 | public: 24 | /** If the widget is nullptr, css/qss will be applied to QApplication */ 25 | static void loadTheme(const QString &themeFile, QWidget *widget = nullptr); 26 | 27 | /** If you have a custom theme, please use loadTheme */ 28 | static void setTheme(int themeStyle, QWidget *widget = nullptr); 29 | }; 30 | -------------------------------------------------------------------------------- /demo/res/windowsflag-normal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/wordwrap.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/windowsflag-normal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include "QxRibbonFactory.h" 9 | 10 | class QX_RIBBON_EXPORT RibbonManager 11 | { 12 | protected: 13 | RibbonManager(); 14 | public: 15 | virtual ~RibbonManager(); 16 | static RibbonManager *instance(); 17 | RibbonFactory *factory(); 18 | void setupFactory(RibbonFactory *factory); 19 | private: 20 | RibbonFactory *m_factory; 21 | }; 22 | 23 | #ifndef RibbonElementMgr 24 | #define RibbonElementMgr RibbonManager::instance() 25 | #endif 26 | 27 | #ifndef RibbonElementFactory 28 | #define RibbonElementFactory RibbonElementMgr->factory() 29 | #endif 30 | 31 | #ifndef RibbonElementStyleOpt 32 | #define RibbonElementStyleOpt RibbonElementFactory->getRibbonStyleOption() 33 | #endif 34 | -------------------------------------------------------------------------------- /pyqt/demo/res/wordwrap.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/removePage.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.so.* 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | object_script.*.Release 15 | object_script.*.Debug 16 | *_plugin_import.cpp 17 | /.qmake.cache 18 | /.qmake.stash 19 | *.pro.user 20 | *.pro.user.* 21 | *.qbs.user 22 | *.qbs.user.* 23 | *.moc 24 | moc_*.cpp 25 | moc_*.h 26 | qrc_*.cpp 27 | ui_*.h 28 | *.qmlc 29 | *.jsc 30 | Makefile* 31 | *build-* 32 | *.qm 33 | *.prl 34 | 35 | # Qt unit tests 36 | target_wrapper.* 37 | 38 | # QtCreator 39 | *.autosave 40 | 41 | # QtCreator Qml 42 | *.qmlproject.user 43 | *.qmlproject.user.* 44 | 45 | # QtCreator CMake 46 | CMakeLists.txt.user* 47 | 48 | # QtCreator 4.8< compilation database 49 | compile_commands.json 50 | 51 | # QtCreator local machine specific files for imported projects 52 | *creator.user* 53 | 54 | *_qmlcache.qrc 55 | 56 | .vscode 57 | -------------------------------------------------------------------------------- /pyqt/demo/res/removePage.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonFactory.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #include "QxRibbonFactory.h" 6 | #include "QxRibbonControls.h" 7 | 8 | RibbonFactory::RibbonFactory() 9 | : m_opt(new RibbonStyleOption()) 10 | { 11 | } 12 | 13 | RibbonFactory::~RibbonFactory() 14 | { 15 | } 16 | 17 | RibbonControlButton *RibbonFactory::createHideGroupButton(QWidget *parent) 18 | { 19 | RibbonControlButton *btn = new RibbonControlButton(parent); 20 | btn->setAutoRaise(false); 21 | btn->setObjectName(QStringLiteral("RibbonBarHideGroupButton")); 22 | btn->setToolButtonStyle(Qt::ToolButtonIconOnly); 23 | return btn; 24 | } 25 | 26 | RibbonStyleOption &RibbonFactory::getRibbonStyleOption() 27 | { 28 | return *m_opt; 29 | } 30 | 31 | void RibbonFactory::setRibbonStyleOption(RibbonStyleOption *opt) 32 | { 33 | m_opt.reset(opt); 34 | } 35 | -------------------------------------------------------------------------------- /pyqt/PyRibbon/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2023 maminjie 3 | # SPDX-License-Identifier: GPL-3.0 4 | 5 | from .QxRibbon import Ribbon 6 | from .QxRibbonWindow import RibbonWindow 7 | from .QxRibbonBar import RibbonBar 8 | from .QxRibbonPage import RibbonPage, RibbonPageContext 9 | from .QxRibbonGroup import RibbonGroup 10 | from .QxRibbonButtonGroup import RibbonButtonGroup 11 | from .QxRibbonControls import RibbonControl, RibbonCheckBox, RibbonComboBox, \ 12 | RibbonControlButton, RibbonLineEdit, RibbonMenu, RibbonSeparator 13 | from .QxRibbonContainers import RibbonCtrlContainer 14 | from .QxRibbonQuickAccessBar import RibbonQuickAccessBar 15 | from .QxRibbonGallery import RibbonGallery, RibbonGalleryGroup 16 | from .QxRibbonButton import RibbonButton 17 | from .QxRibbonApplicationButton import RibbonApplicationButton 18 | from .QxWindowButtonGroup import WindowButtonGroup 19 | -------------------------------------------------------------------------------- /projects/template/config.pri: -------------------------------------------------------------------------------- 1 | !isEmpty(CONFIG_PRI_INCLUDED):error("config.pri already included") 2 | CONFIG_PRI_INCLUDED = 1 3 | 4 | isEmpty(QTPROJECT_VERSION): QTPROJECT_VERSION = 2.0.0 5 | isEmpty(QTPROJECT_COMPAT_VERSION): QTPROJECT_COMPAT_VERSION = 2.0.0 6 | isEmpty(QTPROJECT_DISPLAY_VERSION): QTPROJECT_DISPLAY_VERSION = 2.0.0 7 | isEmpty(QTPROJECT_COPYRIGHT_YEAR): QTPROJECT_COPYRIGHT_YEAR = 2022 8 | 9 | isEmpty(QTPROJECT_DIR): QTPROJECT_DIR = $$PWD 10 | isEmpty(QTPROJECT_OUT_PWD): QTPROJECT_OUT_PWD = $$OUT_PWD 11 | isEmpty(QTPROJECT_PRO_FILE_PWD): QTPROJECT_PRO_FILE_PWD = $$_PRO_FILE_PWD_ 12 | isEmpty(QTPROJECT_PRO_FILE): QTPROJECT_PRO_FILE = $$_PRO_FILE_ 13 | 14 | isEmpty(QTCANPOOL_DIR): QTCANPOOL_DIR = $$quote(D:\projects\qt\qtcanpool) 15 | 16 | isEmpty(QXRIBBON_DIR): QXRIBBON_DIR = $$quote($$PWD/../..) 17 | 18 | INCLUDEPATH += $$QXRIBBON_DIR/src 19 | -------------------------------------------------------------------------------- /src/QxRibbonColorButton.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include "QxRibbonButton.h" 9 | 10 | class RibbonColorButtonPrivate; 11 | 12 | class QX_RIBBON_EXPORT RibbonColorButton : public RibbonButton 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit RibbonColorButton(QWidget *parent = nullptr); 17 | explicit RibbonColorButton(QAction *defaultAction, QWidget *parent = nullptr); 18 | virtual ~RibbonColorButton(); 19 | 20 | const QColor &color() const; 21 | signals: 22 | void colorChanged(const QColor &color); 23 | void colorClicked(const QColor &color, bool checked = false); 24 | public slots: 25 | void setColor(const QColor &color); 26 | private slots: 27 | void onButtonClicked(bool checked = false); 28 | private: 29 | Q_DECLARE_PRIVATE(RibbonColorButton) 30 | }; 31 | -------------------------------------------------------------------------------- /pyqt/demo/res/help.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/folder-stats.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/folder-stats.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/show.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/showContext.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/PyRibbon/QxRibbonQuickAccessBar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2023 maminjie 3 | # SPDX-License-Identifier: GPL-3.0 4 | 5 | 6 | from PyQt5.QtWidgets import QAction, QWidget, QMenu, QToolButton 7 | 8 | from .QxRibbonContainers import RibbonCtrlContainer 9 | from .QxRibbonButtonGroup import RibbonButtonGroup 10 | 11 | 12 | class RibbonQuickAccessBar(RibbonCtrlContainer): 13 | 14 | def __init__(self, parent=None): 15 | super().__init__(parent) 16 | self.m_buttonGroup = RibbonButtonGroup(self) 17 | self.setWidget(self.m_buttonGroup) 18 | 19 | def addSeparator(self): 20 | self.m_buttonGroup.addSeparator() 21 | 22 | def addAction(self, action: QAction): 23 | self.m_buttonGroup.addAction(action) 24 | 25 | def addWidget(self, w: QWidget): 26 | self.m_buttonGroup.addWidget(w) 27 | 28 | def addMenu(self, m: QMenu, pop_mode=QToolButton.InstantPopup): 29 | self.m_buttonGroup.addMenu(m, pop_mode) 30 | -------------------------------------------------------------------------------- /demo/res/folder-table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/folder-table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/demo.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | 3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 | 5 | CONFIG += c++11 6 | 7 | OUT_ROOT = $${OUT_PWD}/.. 8 | TARGET = RibbonDemo 9 | TEMPLATE = app 10 | DESTDIR = $${OUT_ROOT}/bin 11 | 12 | # You can make your code fail to compile if it uses deprecated APIs. 13 | # In order to do so, uncomment the following line. 14 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 15 | 16 | SOURCES += \ 17 | aboutdialog.cpp \ 18 | editablecontainer.cpp \ 19 | main.cpp \ 20 | mainwindow.cpp 21 | 22 | HEADERS += \ 23 | aboutdialog.h \ 24 | editablecontainer.h \ 25 | mainwindow.h 26 | 27 | include($$PWD/../common.pri) 28 | LIBS += -L$${OUT_ROOT}/bin -l$$qtLibraryNameVersion(QxRibbon, 0) 29 | 30 | # Default rules for deployment. 31 | qnx: target.path = /tmp/$${TARGET}/bin 32 | else: unix:!android: target.path = /opt/$${TARGET}/bin 33 | !isEmpty(target.path): INSTALLS += target 34 | 35 | RESOURCES += \ 36 | demo.qrc 37 | 38 | RC_FILE = demo.rc 39 | -------------------------------------------------------------------------------- /src/QxRibbonUtils.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023-2024 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #include "QxRibbonUtils.h" 6 | #include 7 | 8 | namespace QxRibbon { 9 | 10 | QIcon colorIcon(const QColor &color, const QSize &size) 11 | { 12 | QPixmap res(size); 13 | res.fill(Qt::transparent); 14 | QPainter painter(&res); 15 | if (color.isValid()) { 16 | painter.fillRect(QRect(1, 1, res.height() - 2, res.width() - 2), color); 17 | } else { 18 | QPen pen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap); 19 | painter.setPen(pen); 20 | painter.drawRect(QRect(1, 1, res.height() - 2, res.width() - 2)); 21 | pen.setColor(Qt::red); 22 | painter.setPen(pen); 23 | painter.setRenderHint(QPainter::SmoothPixmapTransform, true); 24 | painter.setRenderHint(QPainter::Antialiasing, true); 25 | painter.drawLine(QPoint(1, size.height()), QPoint(size.width() - 1, 1)); 26 | } 27 | return QIcon(res); 28 | } 29 | 30 | } // namespace QxRibbon 31 | -------------------------------------------------------------------------------- /demo/res/folder-checkmark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/folder-checkmark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/undo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 canpool 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /pyqt/demo/res/redo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/folder-add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/folder-star.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/test/test_RibbonGallery.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2023 maminjie 3 | # SPDX-License-Identifier: GPL-3.0 4 | 5 | from PyQt5.QtGui import QIcon 6 | from PyQt5.QtWidgets import QApplication, QWidget, QAction 7 | 8 | from PyRibbon.QxRibbonGallery import RibbonGallery, RibbonGalleryGroup 9 | 10 | 11 | if __name__ == '__main__': 12 | 13 | app = QApplication([]) 14 | mainWindow = QWidget() 15 | 16 | gallery = RibbonGallery(mainWindow) 17 | # gallery.resize(mainWindow.width(), gallery.size().height()) 18 | group = gallery.addGalleryGroup() 19 | group.addActionItem(QAction(QIcon('res/logo.png'), 'test')) 20 | for i in range(10): 21 | group.addItem('test '+str(i), QIcon('res/logo.png')) 22 | 23 | group = RibbonGalleryGroup(mainWindow) 24 | group.setGroupTitle("title") 25 | group.addActionItem(QAction(QIcon('res/logo.png'), 'test')) 26 | gallery.addGalleryGroup(group) 27 | group.setGroupTitle("title changeed") 28 | 29 | mainWindow.setMinimumWidth(500) 30 | mainWindow.resize(500, 300) 31 | mainWindow.show() 32 | app.exec() 33 | -------------------------------------------------------------------------------- /pyqt/demo/res/folder-star.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 canpool 4 | Copyright (c) 2020 czyt1988 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /demo/res/delete.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonQuickAccessBar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023-2024 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | 10 | #include 11 | 12 | 13 | class RibbonQuickAccessBarPrivate; 14 | 15 | /* RibbonQuickAccessBar */ 16 | class QX_RIBBON_EXPORT RibbonQuickAccessBar : public QToolBar 17 | { 18 | Q_OBJECT 19 | public: 20 | explicit RibbonQuickAccessBar(QWidget *parent = Q_NULLPTR); 21 | virtual ~RibbonQuickAccessBar(); 22 | 23 | public: 24 | QAction *actionCustomizeButton() const; 25 | void setActionVisible(QAction *action, bool visible); 26 | bool isActionVisible(QAction *action) const; 27 | int visibleCount() const; 28 | 29 | QByteArray state() const; 30 | void setState(const QByteArray &s); 31 | 32 | Q_SIGNALS: 33 | void showCustomizeMenu(QMenu *menu); 34 | void customizeActionChanged(); 35 | 36 | protected: 37 | virtual bool event(QEvent *event); 38 | virtual void actionEvent(QActionEvent *event); 39 | 40 | private: 41 | QX_DECLARE_PRIVATE(RibbonQuickAccessBar) 42 | }; 43 | -------------------------------------------------------------------------------- /pyqt/demo/res/delete.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonTheme.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023-2024 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #include "QxRibbonTheme.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | void RibbonTheme::loadTheme(const QString &themeFile, QWidget *widget) 12 | { 13 | QFile file(themeFile); 14 | 15 | if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { 16 | return; 17 | } 18 | 19 | QString css = QString::fromUtf8(file.readAll()); 20 | if (widget) { 21 | widget->setStyleSheet(css); 22 | } else { 23 | qApp->setStyleSheet(css); 24 | } 25 | 26 | file.close(); 27 | } 28 | 29 | void RibbonTheme::setTheme(int themeStyle, QWidget *widget) 30 | { 31 | switch (themeStyle) { 32 | case Office2013Theme: 33 | loadTheme(":/theme/res/office2013.css", widget); 34 | break; 35 | case WpsdarkTheme: 36 | loadTheme(":/theme/res/wpsdark.css", widget); 37 | break; 38 | case NormalTheme: 39 | loadTheme(":/theme/res/default.css", widget); 40 | break; 41 | default: 42 | break; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/QxWindowButtonGroupPrivate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2024 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | 10 | class WindowButtonGroup; 11 | 12 | class WindowToolButton : public QPushButton 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit WindowToolButton(QWidget *p = Q_NULLPTR); 17 | }; 18 | 19 | class WindowButtonGroupPrivate : public QObject 20 | { 21 | Q_OBJECT 22 | QX_DECLARE_PUBLIC(WindowButtonGroup) 23 | public: 24 | WindowButtonGroupPrivate(); 25 | 26 | void setupMinimizeButton(bool on); 27 | void setupMaximizeButton(bool on); 28 | void setupCloseButton(bool on); 29 | void updateSize(); 30 | void resize(QSize size); 31 | QSize sizeHint() const; 32 | int groupHeight() const; 33 | public slots: 34 | void buttonClicked(); 35 | public: 36 | WindowToolButton *m_closeButton; 37 | WindowToolButton *m_minimizeButton; 38 | WindowToolButton *m_maximizeButton; 39 | int m_closeStretch; 40 | int m_maxStretch; 41 | int m_minStretch; 42 | qreal m_iconScale; 43 | bool m_signalEnabled; 44 | }; 45 | -------------------------------------------------------------------------------- /src/QxRibbonButtonGroup.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | #include 10 | #include 11 | 12 | class RibbonButtonGroupPrivate; 13 | 14 | class QX_RIBBON_EXPORT RibbonButtonGroup : public QFrame 15 | { 16 | Q_OBJECT 17 | public: 18 | explicit RibbonButtonGroup(QWidget *parent = Q_NULLPTR); 19 | virtual ~RibbonButtonGroup(); 20 | 21 | QAction *addAction(QAction *a); 22 | QAction *addAction(const QString &text, const QIcon &icon, 23 | QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); 24 | QAction *addMenu(QMenu *menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup); 25 | QAction *addSeparator(); 26 | QAction *addWidget(QWidget *w); 27 | 28 | QSize sizeHint() const Q_DECL_OVERRIDE; 29 | QSize minimumSizeHint() const Q_DECL_OVERRIDE; 30 | signals: 31 | void actionTriggered(QAction *action); 32 | protected: 33 | virtual void actionEvent(QActionEvent *e) Q_DECL_OVERRIDE; 34 | private: 35 | QX_DECLARE_PRIVATE(RibbonButtonGroup) 36 | }; 37 | -------------------------------------------------------------------------------- /demo/res/deleteContext.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /projects/template/src/app/app.pro: -------------------------------------------------------------------------------- 1 | include(../../qtproject.pri) 2 | include($$QTCANPOOL_DIR/src/rpath.pri) 3 | 4 | QT += core gui 5 | 6 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 7 | 8 | TARGET = app 9 | TEMPLATE = app 10 | DESTDIR = $$IDE_APP_PATH 11 | 12 | # The following define makes your compiler emit warnings if you use 13 | # any feature of Qt which has been marked as deprecated (the exact warnings 14 | # depend on your compiler). Please consult the documentation of the 15 | # deprecated API in order to know how to port your code away from it. 16 | DEFINES += QT_DEPRECATED_WARNINGS 17 | message($$INCLUDEPATH) 18 | # You can also make your code fail to compile if you use deprecated APIs. 19 | # In order to do so, uncomment the following line. 20 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 21 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 22 | 23 | CONFIG += c++11 24 | 25 | # lib 26 | LIBS *= -l$$qtLibraryNameVersion(QxRibbon, 0) 27 | 28 | SOURCES += \ 29 | main.cpp \ 30 | mainwindow.cpp 31 | 32 | HEADERS += \ 33 | mainwindow.h 34 | 35 | RESOURCES += \ 36 | app.qrc 37 | -------------------------------------------------------------------------------- /pyqt/demo/res/deleteContext.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/useqss.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonStyleOption.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include "QxRibbonBar.h" 9 | #include 10 | 11 | class RibbonStyleOptionPrivate; 12 | 13 | /** 14 | * @brief 定义了 ribbon 所有尺寸相关信息,ribbon 的建立都基于此类的尺寸,如果想调整, 15 | * 可以通过 @ref RibbonFactory(通过 RibbonManager 单例管理) 的 @ref setRibbonStyleOption 16 | * 函数设置自己的 RibbonStyleOption 17 | * 18 | * @sa RibbonManager 19 | * 20 | * 一般 RibbonFactory::setRibbonStyleOption 函数最好在 ribbonbar 构建之前调用 21 | * 22 | * @note 此类定义了 ribbonbar 和 group 的高度信息,并通过字体提前计算好一些布局信息 23 | * 24 | * @todo 后续开发通过配置文件定义 ribbon 的尺寸布局 25 | */ 26 | class QX_RIBBON_EXPORT RibbonStyleOption 27 | { 28 | public: 29 | RibbonStyleOption(); 30 | virtual ~RibbonStyleOption(); 31 | public: 32 | virtual int ribbonBarHeight(RibbonBar::RibbonStyle s) const; 33 | virtual int titleBarHeight() const; 34 | virtual int tabBarHeight() const; 35 | virtual void recalc(); 36 | protected: 37 | virtual int calcRibbonBarHeight(RibbonBar::RibbonStyle s) const; 38 | private: 39 | QX_DECLARE_PRIVATE(RibbonStyleOption) 40 | }; 41 | 42 | QX_RIBBON_EXPORT QDebug operator<<(QDebug debug, const RibbonStyleOption &c); 43 | -------------------------------------------------------------------------------- /pyqt/demo/res/useqss.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/help.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonPageContext.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include "QxRibbonPage.h" 9 | 10 | #include 11 | 12 | class RibbonPageContextPrivate; 13 | 14 | /** 15 | * @brief 管理上下文标签的类 16 | */ 17 | class QX_RIBBON_EXPORT RibbonPageContext : public QObject 18 | { 19 | Q_OBJECT 20 | public: 21 | RibbonPageContext(QWidget *parent = Q_NULLPTR); 22 | ~RibbonPageContext(); 23 | 24 | RibbonPage *addPage(const QString &title); 25 | RibbonPage *page(int index); 26 | 27 | int pageCount() const; 28 | 29 | QList pageList() const; 30 | 31 | bool takePage(RibbonPage *page); 32 | 33 | QVariant id() const; 34 | void setId(const QVariant &id); 35 | 36 | QColor contextColor() const; 37 | void setContextColor(const QColor color); 38 | 39 | QString contextTitle() const; 40 | void setContextTitle(const QString &title); 41 | 42 | signals: 43 | void pageAdded(RibbonPage *page); 44 | void pageRemoved(RibbonPage *page); 45 | protected: 46 | QWidget *parentWidget() const; 47 | virtual bool eventFilter(QObject *watched, QEvent *e) Q_DECL_OVERRIDE; 48 | private: 49 | QX_DECLARE_PRIVATE(RibbonPageContext) 50 | }; 51 | -------------------------------------------------------------------------------- /demo/res/useCustomize.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/useCustomize.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxWindowButtonGroup.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023-2024 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | 10 | class WindowButtonGroupPrivate; 11 | 12 | class QX_RIBBON_EXPORT WindowButtonGroup : public QWidget 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit WindowButtonGroup(QWidget *parent, Qt::WindowFlags flags = Qt::WindowFlags()); 17 | ~WindowButtonGroup(); 18 | 19 | void updateWindowFlags(Qt::WindowFlags flags); 20 | 21 | void setButtonWidthStretch(int close = 4, int max = 3, int min = 3); 22 | void setIconScale(qreal iconscale = 0.5); 23 | void setWindowStates(Qt::WindowStates s); 24 | 25 | virtual QSize sizeHint() const Q_DECL_OVERRIDE; 26 | 27 | /** default is disabled */ 28 | bool signalIsEnabled() const; 29 | public Q_SLOTS: 30 | void setSignalEnabled(bool enable); 31 | Q_SIGNALS: 32 | void buttonMinimizeClicked(); 33 | void buttonMaximzieClicked(); 34 | void buttonCloseClicked(); 35 | 36 | protected: 37 | virtual bool eventFilter(QObject *watched, QEvent *e) Q_DECL_OVERRIDE; 38 | virtual void parentResize(); 39 | virtual void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; 40 | private: 41 | QX_DECLARE_PRIVATE(WindowButtonGroup) 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /pyqt/demo/res/item.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/res.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | res/ribbonGroupOptionButton.png 4 | res/ArrowDown.png 5 | res/ArrowMore.png 6 | res/ArrowUp.png 7 | res/Titlebar_Close.png 8 | res/Titlebar_Close_Hover.png 9 | res/Titlebar_Max.png 10 | res/Titlebar_Min.png 11 | res/Titlebar_Normal.png 12 | res/Titlebar_Shade.png 13 | res/Titlebar_Unshade.png 14 | res/lighter/ribbonGroupOptionButton.png 15 | res/lighter/ArrowDown.png 16 | res/lighter/ArrowMore.png 17 | res/lighter/ArrowUp.png 18 | res/lighter/Titlebar_Close.png 19 | res/lighter/Titlebar_Close_Hover.png 20 | res/lighter/Titlebar_Max.png 21 | res/lighter/Titlebar_Min.png 22 | res/lighter/Titlebar_Normal.png 23 | res/lighter/Titlebar_Shade.png 24 | res/lighter/Titlebar_Unshade.png 25 | 26 | 27 | res/default.css 28 | res/office2013.css 29 | res/wpsdark.css 30 | 31 | 32 | -------------------------------------------------------------------------------- /demo/res/bold.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/bold.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/hideRibbon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/long-text.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(RibbonDemo) 3 | 4 | set(QX_RIBBON_DEMO_NAME RibbonDemo) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | 7 | set(CMAKE_CXX_STANDARD 11) 8 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 9 | 10 | find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) 11 | find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Widgets REQUIRED) 12 | 13 | set(PROJECT_SOURCES 14 | mainwindow.h 15 | mainwindow.cpp 16 | aboutdialog.h 17 | aboutdialog.cpp 18 | editablecontainer.h 19 | editablecontainer.cpp 20 | main.cpp 21 | demo.qrc 22 | ) 23 | 24 | add_executable(${QX_RIBBON_DEMO_NAME} 25 | ${PROJECT_SOURCES} 26 | ) 27 | 28 | target_link_libraries(${QX_RIBBON_DEMO_NAME} PUBLIC 29 | Qt${QT_VERSION_MAJOR}::Core 30 | Qt${QT_VERSION_MAJOR}::Gui 31 | Qt${QT_VERSION_MAJOR}::Widgets 32 | ) 33 | 34 | set(QX_RIBBON_LIB_NAME QxRibbon${QX_RIBBON_VERSION_MAJOR}) 35 | find_library(QxRibbon NAMES "${QX_RIBBON_LIB_NAME}") 36 | target_link_libraries(${QX_RIBBON_DEMO_NAME} PRIVATE "${QX_RIBBON_LIB_NAME}") 37 | 38 | set_target_properties(${QX_RIBBON_DEMO_NAME} PROPERTIES 39 | AUTOMOC ON 40 | AUTORCC ON 41 | AUTOUIC ON 42 | CXX_EXTENSIONS OFF 43 | EXPORT_NAME ${QX_RIBBON_DEMO_NAME} 44 | ARCHIVE_OUTPUT_DIRECTORY "${QX_RIBBON_BIN_DIR}/lib" 45 | LIBRARY_OUTPUT_DIRECTORY "${QX_RIBBON_BIN_DIR}/lib" 46 | RUNTIME_OUTPUT_DIRECTORY "${QX_RIBBON_BIN_DIR}/bin" 47 | ) 48 | -------------------------------------------------------------------------------- /pyqt/demo/res/long-text.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/remove-app-btn.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/remove-app-btn.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/FramelessHelper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023-2024 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 11 | #define QTRESULT qintptr 12 | #else 13 | #define QTRESULT long 14 | #endif // QTRESULT 15 | 16 | class QWidget; 17 | class FramelessHelperPrivate; 18 | 19 | class FramelessHelper : public QObject, public QAbstractNativeEventFilter 20 | { 21 | Q_OBJECT 22 | public: 23 | explicit FramelessHelper(QObject *parent); 24 | ~FramelessHelper(); 25 | 26 | void addWidget(QWidget *w); 27 | void removeWidget(QWidget *w); 28 | 29 | bool widgetResizable() const; 30 | void setWidgetResizable(bool resizable); 31 | 32 | bool widgetMovable() const; 33 | void setWidgetMovable(bool movable); 34 | 35 | int titleHeight() const; 36 | void setTitleHeight(int height); 37 | 38 | int borderWidth() const; 39 | void setBorderWidth(int width); 40 | 41 | void addCaptionClassName(const QString &name); 42 | 43 | signals: 44 | void windowIconChanged(const QIcon &icon); 45 | void windowTitleChanged(const QString &title); 46 | void windowStateChanged(Qt::WindowStates state); 47 | 48 | protected: 49 | virtual bool eventFilter(QObject *object, QEvent *event); 50 | virtual bool nativeEventFilter(const QByteArray &eventType, void *message, QTRESULT *result); 51 | 52 | private: 53 | FramelessHelperPrivate *d; 54 | }; 55 | -------------------------------------------------------------------------------- /demo/res/enableTest.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/enableTest.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/show.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/gallery/Adobe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/gallery/Adobe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonContainers.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | 10 | /** 11 | * @brief Control Widget Container 12 | * 13 | * Qt::Horizontal (default) 14 | * ------------------------ 15 | * | icon | text | widget | 16 | * ------------------------ 17 | * 18 | * Qt::Vertical 19 | * ------------------------ 20 | * | icon | text | 21 | * ------------------------ 22 | * | | 23 | * | widget | 24 | * | | 25 | * ------------------------ 26 | */ 27 | class RibbonCtrlContainerPrivate; 28 | class QX_RIBBON_EXPORT RibbonCtrlContainer : public QWidget 29 | { 30 | Q_OBJECT 31 | public: 32 | explicit RibbonCtrlContainer(QWidget *parent = Q_NULLPTR); 33 | explicit RibbonCtrlContainer(Qt::Orientation orientation, QWidget *parent = Q_NULLPTR); 34 | virtual ~RibbonCtrlContainer(); 35 | 36 | void setIconVisible(bool b); 37 | void setTitleVisible(bool b); 38 | 39 | void setIcon(const QIcon &i); 40 | QIcon icon() const; 41 | 42 | void setIconSize(const QSize &size); 43 | QSize iconSize() const; 44 | 45 | void setText(const QString &t); 46 | QString text() const; 47 | 48 | void setWidget(QWidget *w); 49 | QWidget *widget() const; 50 | 51 | Qt::Orientation orientation() const; 52 | void setOrientation(Qt::Orientation orientation); 53 | private: 54 | QX_DECLARE_PRIVATE(RibbonCtrlContainer) 55 | }; 56 | -------------------------------------------------------------------------------- /src/QxRibbonGroupPrivate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include "QxRibbonGroup.h" 9 | 10 | #include 11 | 12 | class RibbonButton; 13 | class RibbonGroupItem; 14 | class RibbonGroupLayout; 15 | 16 | /** 17 | * @brief Group右下角的操作按钮 18 | * 19 | * 此按钮和一个action关联,使用 @ref RibbonGroup::addOptionAction 函数用于生成此按钮 20 | * 21 | */ 22 | class RibbonGroupOptionButton : public QToolButton 23 | { 24 | Q_OBJECT 25 | public: 26 | explicit RibbonGroupOptionButton(QWidget *parent = Q_NULLPTR); 27 | // 有别于setDefaultAction 此函数只关联action的响应,而不设置text,icon等 28 | void connectAction(QAction *action); 29 | }; 30 | 31 | class RibbonGroupPrivate 32 | { 33 | QX_DECLARE_PUBLIC(RibbonGroup) 34 | public: 35 | RibbonGroupPrivate(); 36 | 37 | void init(); 38 | void resetLargeToolButtonStyle(); 39 | 40 | // 返回最后一个添加的action对应的button,前提是最后一个是toolbutton,否则返回Q_NULLPTR 41 | RibbonButton *lastAddedButton(); 42 | // RibbonGroup的友元类RibbonCustommizeWidget会通过该接口获取所有item 43 | const QList &ribbonGroupItems() const; 44 | public: 45 | RibbonGroupLayout *m_layout; 46 | RibbonGroupOptionButton *m_optionActionButton; 47 | RibbonGroup::GroupLayoutMode m_groupLayoutMode; ///< group的布局模式,默认为3行模式ThreeRowMode 48 | static int s_groupTitleHeight; ///< group标题栏的全局高度,默认为21 49 | static bool s_titleVisible; 50 | bool m_isCanCustomize; ///< 记录是否可自定义 51 | }; 52 | -------------------------------------------------------------------------------- /pyqt/demo/res/save.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/Align-Left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/Align-Right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/unlock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/Align-Center.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/unlock.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/hideRibbon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/ContextPage.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/logo64.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demo/res/gallery/File-Readonly.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/gallery/File-Readonly.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/showContext.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demo/res/gallery/Illustrator.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/gallery/Illustrator.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/gallery/File-Error.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/gallery/File-Error.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/folder-cog.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/folder-cog.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/Decrease-Indent.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/gallery/Download-File.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/gallery/Download-File.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/QxRibbonCustomizeDialog.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | 10 | class QXmlStreamWriter; 11 | class QXmlStreamReader; 12 | 13 | class RibbonActionsManager; 14 | class RibbonCustomizeDialogUi; 15 | class RibbonBar; 16 | 17 | /** 18 | * @brief RibbonCustomizeWidget 的对话框封装 19 | * 20 | * 此功能依赖于 @ref RibbonActionsManager ,RibbonActionsManager 建议作为 mianwindow 的成员变量, 21 | * RibbonActionsManager 可以快速绑定所有 QAction,详细见 RibbonActionsManager 的说明 22 | * 23 | * @note Ribbon 的自定义是基于步骤的,如果在窗口生成前调用了 @ref QxRibbonCustomizeApplyFromXmlFile 类似函数 24 | * 那么在对话框执行前为了保证同步需要调用 @ref RibbonCustomizeDialog::fromXml 25 | * 同步配置文件,这样再次修改后的配置文件就一致 26 | */ 27 | class QX_RIBBON_EXPORT RibbonCustomizeDialog : public QDialog 28 | { 29 | Q_OBJECT 30 | public: 31 | RibbonCustomizeDialog(RibbonBar *ribbonBar, QWidget *p = Q_NULLPTR, 32 | Qt::WindowFlags f = Qt::WindowFlags()); 33 | 34 | // 设置action管理器 35 | void setupActionsManager(RibbonActionsManager *mgr); 36 | 37 | // 应用所有的设定 38 | bool applys(); 39 | 40 | // 清除所有动作 41 | void clear(); 42 | 43 | // 转换为xml 44 | bool toXml(QXmlStreamWriter *xml) const; 45 | bool toXml(const QString &xmlpath) const; 46 | 47 | // 从xml中加载QList,对于基于配置文件的设置,对话框显示前建议调用此函数,保证叠加设置的正确记录 48 | void fromXml(QXmlStreamReader *xml); 49 | void fromXml(const QString &xmlpath); 50 | 51 | private: 52 | void initConnection(); 53 | 54 | RibbonCustomizeDialogUi *ui; 55 | }; 56 | 57 | /** 58 | * @brief 直接加载xml自定义ribbon配置文件用于ribbon的自定义显示 59 | * @param filePath xml配置文件 60 | * @param bar 61 | * @param mgr action管理器 62 | * @return 成功返回true 63 | * @note 重复加载一个配置文件会发生异常,为了避免此类事件发生,一般通过一个变量保证只加载一次,如: 64 | * @code 65 | * static bool has_call = false; 66 | * if (!has_call) { 67 | * has_call = QxRibbonCustomizeApplyFromXmlFile("customize.xml", this->ribbonBar(), m_actMgr); 68 | * } 69 | * @endcode 70 | */ 71 | bool QX_RIBBON_EXPORT QxRibbonCustomizeApplyFromXmlFile(const QString &filePath, RibbonBar *bar, 72 | RibbonActionsManager *mgr); 73 | -------------------------------------------------------------------------------- /demo/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // 重定向qdebug的打印 8 | void log_out_put(QtMsgType type, const QMessageLogContext &context, const QString &msg); 9 | 10 | /** 11 | * @brief 重定向qdebug的打印 12 | * @param type 13 | * @param context 14 | * @param msg 15 | */ 16 | void log_out_put(QtMsgType type, const QMessageLogContext &context, const QString &msg) 17 | { 18 | QByteArray localMsg = msg.toLocal8Bit(); 19 | 20 | switch (type) { 21 | case QtDebugMsg: 22 | fprintf(stdout, "[Debug] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); 23 | break; 24 | case QtInfoMsg: 25 | fprintf(stdout, "[Info] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); 26 | break; 27 | case QtWarningMsg: 28 | fprintf(stdout, "[Warning] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); 29 | break; 30 | case QtCriticalMsg: 31 | fprintf(stdout, "[Critical] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); 32 | break; 33 | case QtFatalMsg: 34 | fprintf(stdout, "[Fatal] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); 35 | abort(); 36 | break; 37 | default: 38 | fprintf(stdout, "[Debug] %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); 39 | break; 40 | } 41 | #ifndef QT_NO_DEBUG_OUTPUT 42 | fflush(stdout); 43 | #endif 44 | } 45 | 46 | int main(int argc, char *argv[]) 47 | { 48 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) 49 | QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 50 | #endif 51 | QApplication a(argc, argv); 52 | qInstallMessageHandler(log_out_put); 53 | QFont f = a.font(); 54 | 55 | f.setFamily("Microsoft YaHei"); 56 | a.setFont(f); 57 | 58 | QElapsedTimer cost; 59 | 60 | cost.start(); 61 | MainWindow w; 62 | 63 | qDebug() << "window build cost:" << cost.elapsed() << " ms"; 64 | w.show(); 65 | 66 | return (a.exec()); 67 | } 68 | -------------------------------------------------------------------------------- /src/QxRibbonButtonPrivate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonButton.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | class RibbonButtonPrivate 14 | { 15 | public: 16 | QX_DECLARE_PUBLIC(RibbonButton) 17 | public: 18 | RibbonButtonPrivate(); 19 | virtual ~RibbonButtonPrivate(); 20 | 21 | QStyle *style() const; 22 | 23 | void recalcSizeHint(QStyleOptionToolButton &opt, QSize s); 24 | // 此函数用来计算icon和text的尺寸 25 | // 注意icon的尺寸依赖text,且只要知道字体大小就可以确定icon的高度 26 | void calcIconAndTextRect(const QStyleOptionToolButton &opt); 27 | // 在需要绘制文字的时候调用此函数,有些效果需要文字的文字改变 28 | QRect adjustedTextRect(const QStyleOptionToolButton &opt, const QWidget *w); 29 | QRect calcIndicatorArrowDownRect(const QStyleOptionToolButton &opt); 30 | virtual QPixmap createIconPixmap(const QStyleOptionToolButton &opt, const QSize &iconsize); 31 | // 根据鼠标位置更新按钮的信息 32 | void updateButtonState(const QPoint &pos); 33 | 34 | void drawButton(QStyleOptionToolButton &opt, QPainter &p, const QWidget *w); 35 | void drawIconAndLabel(QStyleOptionToolButton &opt, QPainter &p, const QWidget *w); 36 | void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbutton, const QRect &rect, 37 | QPainter *painter, const QWidget *widget = Q_NULLPTR); 38 | 39 | public: 40 | RibbonButton::RibbonButtonType m_buttonType; 41 | RibbonButton::LargeButtonType m_largeButtonType; 42 | bool m_mouseOnSubControl; ///< 这个用于标记MenuButtonPopup模式下,鼠标在文本区域 43 | bool m_menuButtonPressed; 44 | bool m_isWordWrap; ///< 标记是否文字换行 @default false 45 | int m_iconAndTextSpace; ///< 按钮和边框的距离 46 | QSize m_sizeHint; ///< 保存计算好的sizehint 47 | QRect m_iconRect; ///< 记录icon的绘制位置 48 | QRect m_textRect; ///< 记录text的绘制位置 49 | QRect m_indicatorArrowRect; ///< 记录IndicatorArrow的绘制位置 50 | 51 | static bool s_isToolButtonTextShift; ///< 配置RibbonButton文字在点击时是否会轻微改变位置而达到一种类似跳动的效果, 52 | ///< @default 默认为false 53 | static bool s_liteStyleEnableWordWrap; ///< 在lite模式下是否允许文字换行,如果允许,则图标相对比较小,默认不允许 54 | }; 55 | -------------------------------------------------------------------------------- /pyqt/demo/res/Decrease-Margin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/clipboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/QxRibbonControls.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* RibbonControl */ 17 | class QX_RIBBON_EXPORT RibbonControl : public QWidget 18 | { 19 | Q_OBJECT 20 | public: 21 | explicit RibbonControl(QWidget *parent = Q_NULLPTR); 22 | }; 23 | 24 | /* RibbonCheckBox */ 25 | class QX_RIBBON_EXPORT RibbonCheckBox : public QCheckBox 26 | { 27 | Q_OBJECT 28 | public: 29 | explicit RibbonCheckBox(QWidget *parent = Q_NULLPTR); 30 | }; 31 | 32 | /* RibbonComboBox */ 33 | class QX_RIBBON_EXPORT RibbonComboBox : public QComboBox 34 | { 35 | Q_OBJECT 36 | public: 37 | explicit RibbonComboBox(QWidget *parent = Q_NULLPTR); 38 | }; 39 | 40 | /* RibbonControlButton */ 41 | class QX_RIBBON_EXPORT RibbonControlButton : public QToolButton 42 | { 43 | Q_OBJECT 44 | public: 45 | explicit RibbonControlButton(QWidget *parent = Q_NULLPTR); 46 | }; 47 | 48 | /* RibbonLineEdit */ 49 | class QX_RIBBON_EXPORT RibbonLineEdit : public QLineEdit 50 | { 51 | Q_OBJECT 52 | public: 53 | explicit RibbonLineEdit(QWidget *parent = Q_NULLPTR); 54 | }; 55 | 56 | /* RibbonMenu */ 57 | class QX_RIBBON_EXPORT RibbonMenu : public QMenu 58 | { 59 | Q_OBJECT 60 | public: 61 | explicit RibbonMenu(QWidget *parent = Q_NULLPTR); 62 | explicit RibbonMenu(const QString &title, QWidget *parent = Q_NULLPTR); 63 | 64 | QAction *addRibbonMenu(RibbonMenu *menu); 65 | RibbonMenu *addRibbonMenu(const QString &title); 66 | RibbonMenu *addRibbonMenu(const QIcon &icon, const QString &title); 67 | QAction *addWidget(QWidget *w); 68 | }; 69 | 70 | /* RibbonSeparator */ 71 | class QX_RIBBON_EXPORT RibbonSeparator : public QWidget 72 | { 73 | Q_OBJECT 74 | public: 75 | RibbonSeparator(int height, QWidget *parent = Q_NULLPTR); 76 | RibbonSeparator(QWidget *parent = Q_NULLPTR); 77 | 78 | virtual QSize sizeHint() const Q_DECL_OVERRIDE; 79 | void setTopBottomMargins(int top, int bottom); 80 | protected: 81 | void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; 82 | private: 83 | int m_topMargin; 84 | int m_bottomMargin; 85 | }; 86 | -------------------------------------------------------------------------------- /demo/res/gallery/Drive-File.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/gallery/Document-File.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/gallery/Drive-File.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/gallery/Document-File.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/res/gallery/Favorit-File.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/gallery/Favorit-File.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/PyRibbon/QxRibbonContainers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2023 maminjie 3 | # SPDX-License-Identifier: GPL-3.0 4 | 5 | from PyQt5.QtCore import Qt, QSize 6 | from PyQt5.QtGui import QIcon 7 | from PyQt5.QtWidgets import QWidget, QHBoxLayout, QLabel, QSizePolicy 8 | 9 | 10 | class RibbonCtrlContainer(QWidget): 11 | 12 | def __init__(self, parent=None): 13 | super().__init__(parent) 14 | self.m_widget = None 15 | self.m_icon = QIcon() 16 | self.m_iconSize = QSize(18, 18) 17 | 18 | self.m_layout = QHBoxLayout(self) 19 | self.m_layout.setSpacing(0); 20 | self.m_layout.setObjectName("layout"); 21 | self.m_layout.setContentsMargins(0, 0, 0, 0); 22 | 23 | self.m_labelPixmap = QLabel(self) 24 | self.m_labelPixmap.setObjectName("labelPixmap") 25 | self.m_labelPixmap.setAlignment(Qt.AlignCenter) 26 | self.m_layout.addWidget(self.m_labelPixmap) 27 | 28 | self.m_labelText = QLabel(self) 29 | self.m_labelText.setObjectName("labelTest") 30 | self.m_layout.addWidget(self.m_labelText) 31 | 32 | def setIconVisible(self, b: bool): 33 | self.m_labelPixmap.setVisible(b) 34 | 35 | def setTitleVisible(self, b: bool): 36 | self.m_labelText.setVisible(b) 37 | 38 | def setIcon(self, i: QIcon): 39 | self.m_icon = i 40 | self.m_labelPixmap.setPixmap(i.pixmap(self.m_iconSize)) 41 | 42 | def getIcon(self) -> QIcon: 43 | return self.m_icon 44 | 45 | def setText(self, t: str): 46 | self.m_labelText.setText(t) 47 | 48 | def getText(self) -> str: 49 | return self.m_labelText.text() 50 | 51 | def hasWidget(self) -> bool: 52 | return self.m_widget is not None 53 | 54 | def setWidget(self, w: QWidget): 55 | if self.m_widget: 56 | old_widget = self.m_widget 57 | i = self.m_layout.indexOf(old_widget) 58 | if i >= 0: 59 | self.m_layout.takeAt(i) 60 | self.m_widget = w 61 | if not w: 62 | return 63 | if w.parent() != self: 64 | w.setParent(self) 65 | self.m_layout.addWidget(w) 66 | sp = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) 67 | sp.setHorizontalStretch(0) 68 | sp.setVerticalStretch(0) 69 | w.setSizePolicy(sp) 70 | 71 | def getWidget(self) -> QWidget: 72 | return self.m_widget 73 | -------------------------------------------------------------------------------- /src/QxRibbonButton.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyleft (C) 2023 maminjie 3 | * SPDX-License-Identifier: MIT 4 | **/ 5 | #pragma once 6 | 7 | #include "QxRibbonGlobal.h" 8 | #include 9 | 10 | class RibbonButtonPrivate; 11 | /** 12 | * @brief Ribbon 界面适用的 toolButton 13 | * 14 | * 相对于普通 toolbutton,主要多了两个类型设置, @ref setButtonType 和 @ref setLargeButtonType 15 | * 16 | * @note @sa setIconSize 函数不在起作用 17 | */ 18 | class QX_RIBBON_EXPORT RibbonButton : public QToolButton 19 | { 20 | Q_OBJECT 21 | public: 22 | enum RibbonButtonType { 23 | LargeButton, 24 | SmallButton 25 | }; 26 | Q_ENUM(RibbonButtonType) 27 | 28 | enum LargeButtonType { 29 | Normal, ///< icon占大按钮的一半区域, 箭头在按钮最下方,文字可以换一行,对应于office的菜单按钮,下箭头在按钮最下方(默认) 30 | Lite ///< icon占大按钮的60%,文字占40%,且文字不换行,对应于wps模式的菜单按钮,下箭头在文字旁边 31 | }; 32 | public: 33 | explicit RibbonButton(QWidget *parent = Q_NULLPTR); 34 | explicit RibbonButton(QAction *defaultAction, QWidget *parent = Q_NULLPTR); 35 | virtual ~RibbonButton(); 36 | 37 | RibbonButtonType buttonType() const; 38 | void setButtonType(RibbonButtonType type); 39 | 40 | void setLargeButtonType(LargeButtonType type); 41 | LargeButtonType largeButtonType() const; 42 | 43 | virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; 44 | virtual QSize sizeHint() const Q_DECL_OVERRIDE; 45 | public: 46 | static void setToolButtonTextShift(bool on); 47 | static bool isToolButtonTextShift(); 48 | static void setLiteStyleEnableWordWrap(bool on); 49 | static bool isLiteStyleEnableWordWrap(); 50 | protected: 51 | virtual bool event(QEvent *e) Q_DECL_OVERRIDE; 52 | virtual void changeEvent(QEvent *e) Q_DECL_OVERRIDE; 53 | virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; 54 | virtual void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; 55 | virtual void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE; 56 | virtual void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; 57 | virtual void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE; 58 | virtual void focusOutEvent(QFocusEvent *e) Q_DECL_OVERRIDE; 59 | virtual void leaveEvent(QEvent *e) Q_DECL_OVERRIDE; 60 | virtual bool hitButton(const QPoint &pos) const Q_DECL_OVERRIDE; 61 | virtual void actionEvent(QActionEvent *e) Q_DECL_OVERRIDE; 62 | protected: 63 | explicit RibbonButton(RibbonButtonPrivate *d, QWidget *parent = Q_NULLPTR); 64 | protected: 65 | QX_DECLARE_PRIVATE(RibbonButton) 66 | }; 67 | -------------------------------------------------------------------------------- /demo/res/gallery/Photoshop.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pyqt/demo/res/gallery/Photoshop.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------