开源五线谱打谱软件MuseScore代码分析之二:MuseScore的图形元素
上次讨论了一首MuseScore的内存结构,可知一首歌曲的大概结构是:score { parts, staffs, measures{ segments{ chordrest, clef, key, time, barline, etc,.} , elements, tuplets } }这些可见或不可见的元素,大多继承自Element类。
Element类是所有图形元素的基类,每一个Element都含有如下内容:
- score位置:
_parent 指向父元素;_score 指向所属歌曲;
add(Element*),remove(Element*),change(Element* o, Element* n) 用于修改子元素,只有少数Element含有子元素,大部分都是仅有 _parent,即树中的叶子节点。
- 显示位置 :在屏幕,打印机等的显示位置。
_pos 是相对于parent的位移;
_userOff 是用户自定义偏移,这两个之和是实际的位置;
_bbox 在排版完成后记录元素的外框,是一个长方形,是元素查找定位的依据。
- 音乐位置:在歌曲中的位置,
横向的时间位置是 _tick ,
纵向的音轨位置有 _track,mscore 每一行谱表固定包含4个voice,即五线谱记谱法中的多声部,这个track的计算是包括voice偏移的。例如一个钢琴乐器的高低音谱表treble-bass clef,treble含有4个voices(0~3),则bass上的Element一开始的_track是4。
- 排版功能:
每个Element都含有layout()排版函数,继承类重写该函数实现排版功能,做相对于parent的伸展运动。
draw(QPainter&)函数在layout()完成后调用,将执行实际的绘制工作。
- 数据编辑功能:
mscore支持的编辑方式有两种,一是鼠标选中后,在右键菜单里选进一步的功能,另一种是选中palette工具箱中的元素,往谱子上拖拽,实现添加元素的功能,或选中元素后再拖拽。选中(select)时,程序调用bbox()得到Element外框判断是否选择,调用setSelected() 函数设置选中。拖拽(drag & drop)时由 drag(const QPointF& s),endDrag(),dragAnchor(),acceptDrop(),drop() 等函数实现,由派生类实现。
- 文件读写:
mscore 的文档格式是 xml 的,每个Element都有read(QDomElement e), write(Xml& xml) 函数,从xml文本节点中读取数据,或把自身数据转换成xml文本节点,这种实现方式我个人不怎么喜欢。
下面来张大图,是 svn 当前版本的 Element 继承关系类图。


浙公网安备 33010602011771号