# Element-UI with Qt widgets **Repository Path**: top_xiong/element-ui-with-qt-widgets ## Basic Information - **Project Name**: Element-UI with Qt widgets - **Description**: 一个使用Qt Widgets编写的Element-UI风格组件库 - **Primary Language**: C/C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2024-11-30 - **Last Updated**: 2024-11-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Element-UI with Qt Widgets #### 介绍 一个使用Qt Widgets编写的Element-UI风格组件库 #### 主要类结构 ![类图](class-diagram.png) #### 绘制组件的具体步骤 - 前言 ​ 每个组件继承自`ElComponent`类,这是一个抽象类,里面存在一个**纯虚函数`initPalette`**,派生类通过实现该虚函数来为组件设置调色板`ElPalette`,以下是`ElCheckbox`的实现代码: ```C++ void ElCheckbox::initPalette() { // background is default color, which is white. _palette.setColor(ElPalette::Border, ThemeColor::lineColor); _palette.setColor(ElPalette::Foreground, ThemeColor::textPrimaryColor); _palette.toggleColorGroup(ElPalette::Entered); _palette.setColor(ElPalette::Border, ThemeColor::lineColor); _palette.setColor(ElPalette::Foreground, ThemeColor::textPrimaryColor); _palette.toggleColorGroup(ElPalette::Pressed); _palette.setColor(ElPalette::Background, ThemeColor::primaryShallowColor); _palette.setColor(ElPalette::Border, ThemeColor::primaryColor); _palette.setColor(ElPalette::Foreground, ThemeColor::textPrimaryColor); _palette.toggleColorGroup(ElPalette::Disabled); _palette.setColor(ElPalette::Border, ThemeColor::lineDisabledColor); _palette.setColor(ElPalette::Foreground, ThemeColor::textDisabledColor); _palette.toggleColorGroup(ElPalette::Normal); } ``` ​ `_palette`是`ElPalette`对象,它是`ElComponent`的一个**保护(protected)数据成员**。 > [!NOTE] > > 这里我们简要地介绍一下`ElPalette`。 > > 这个类灵感来自`QPalette`,拥有两个私有数据成员: > > ```C++ > ColorGroup _currentColorGroup = Normal; > QMap, QColor> _colors; > ``` > > `ColorGroup`和`ColorRole`参照`QPalette`对应的类型,都是枚举类型,分别代表组件不同时期的状态(如鼠标移入状态等)和需要填充颜色的部分(边框、背景、前景部分)。这样一来用户也能通过调色板自定义组件的相关颜色。 - 绘制 ​ 可以看到,我们在`initPalette`中为不同的组件状态设置了不同的颜色,就相当于我们为画布调好了配色,接下来不要忘了重要的一步,**在构造函数中调用这个纯虚函数**(虽然这样来说是存在潜在问题的),然后我们就可以开始画画咯~而本项目主要以**重写paintEvent事件**来绘制组件。 ​ 这里我介绍我绘制时的一般步骤,对于有文字描述的组件,先使用`void QPainter::drawText()`函数获取文字的绑定矩形(bounding rect),这个矩形的好处在于**不论绘制区域所在的矩形如何,我们都能得到这段文字形成的矩形**,那么绘制的区域我们并不关心,所以代码可以写成`painter.drawText(QRect(), Qt::AlignCenter, text, &boundingRect);`,重要的是`boundingRect`,这样不论多长的文字,我们都能很好的让组件去适应它。 ​ 因此接下来的步骤就是`resize()`,一般为了组件更加美观,我会定义一些padding, spacing值,它们都会被定义为静态的(目前暂时为私有的,后续会考虑让用户自定义这些值而做出改变)。显然这些值会影响组件的大小。 ​ 之后便是使用`_palette.color(ElPalette::Background)`画组件的矩形区域,`ElPalette::Border`画对应的边框,`ElPalette::Foreground`画对应的文字颜色。其他部分不同的组件存在不同的画法,没法概括的说。 ​ 结束`paintEvent`后,我们需要**处理组件不同状态的变化**,这里拿`ElPalette::Normal`、`ElPalette::Entered`、`ElPalette::Pressed`三个状态举例子,这三个状态在`ElButton`中分别需要重写`enterEvent()`、`leaveEvent()`、`mousePressEvent()`、`mouseReleaseEvent()`,在事件重写函数中通过`void ElPalette::toggleColorGroup()`切换当前的`ColorGroup`(即状态),但不要忘记`update()`。 ​ 你觉得是不是结束了?呃……对于某些**存在禁用(disabled)状态**的组件来说还没完,因为它们还需要切换禁用状态,可是也不存在什么`enableEvent()`或者是`disableEvent()`呀?但如果Qt没有为我们专门提供某些事件类型的事件函数,我们就应该重写`bool QWidget::event(QEvent *e)`。`QEvent`有一个事件类型叫`QEvent::EnabledChange`可以做到这件事,接下来你知道怎么做了吧。 ​ 以上是本人绘制(仅仅只是绘制哦)本项目组件的一般流程,如果你有更妙的方法,欢迎贡献。 **好了,现在你已经熟悉这个项目了,速速为这个项目贡献你的一份力量吧!力量吧!量吧!吧!!:fire:** #### 命名规范 ​ 如有意向参与开发,应当遵循本项目的以下命名规范: - 头文件和源文件名所有字母都小写; - 类名采用大驼峰命名; - 非公有数据成员以下划线`_`开头,后面采用驼峰命名或下划线命名; - 公有函数采用小驼峰命名,非公有函数禁止大驼峰命名,小驼峰命名或下划线命名均可; - 局部变量为了与数据成员作区分,应当最好避免以下划线`_`开头; - 静态数据成员采用大驼峰与下划线结合的方式命名,如`Padding_Lr`表示左右边框与内容的距离; - 静态成员函数与普通成员函数的命名一致; - 尽量不要定义全局作用域下的成员。 #### 安装教程 使用Qt Creator或其他IDE编译源文件即可。 #### 使用说明 本项目仍在开发中... 完全开发后会考虑**导出为`designer`组件**。 #### 参与贡献 1. 提交PR 1. 联系我,加入我的仓库(我很随意的) #### 鸣谢 本项目灵感源于[Element UI](https://element.eleme.cn/#/zh-CN/component/installation)以及[QML Fluent UI](https://github.com/zhuzichu520/FluentUI)。