QCAD中的监听模式

监听模式

一种一对多的关系,多个观察者(Observer)监听同一个被观察者(Subject)。被观察者对象在状态或数据发生变化时,会通知所有观察者对象,使它们做出相应的变化。

类图

csdn mermaid :

classDiagram

    Subject<|--SubjectImpl:继承

    Observer<|--ObserverImpl:继承

    Subject *--Observer:组成

    SubjectImpl<..ObserverImpl:依赖

    class Subject{
      - List~Observer~ observers
      + addObserver(Observer) void
      + removeObserver(Observer) void
      + notifyObservers(Object) void
    }

    class SubjectImpl{
      - Object data
      + change()
    }
    class Observer{
      + update(Subject,Object) void
    }
    class ObserverImpl{
      + update(Subject,Object) void
    }  

#mermaid-svg-ip8qsfFO2ChiKEOC .label{font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family);fill:#333;color:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .label text{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .node rect,#mermaid-svg-ip8qsfFO2ChiKEOC .node circle,#mermaid-svg-ip8qsfFO2ChiKEOC .node ellipse,#mermaid-svg-ip8qsfFO2ChiKEOC .node polygon,#mermaid-svg-ip8qsfFO2ChiKEOC .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-ip8qsfFO2ChiKEOC .node .label{text-align:center;fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .node.clickable{cursor:pointer}#mermaid-svg-ip8qsfFO2ChiKEOC .arrowheadPath{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-ip8qsfFO2ChiKEOC .flowchart-link{stroke:#333;fill:none}#mermaid-svg-ip8qsfFO2ChiKEOC .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-ip8qsfFO2ChiKEOC .edgeLabel rect{opacity:0.9}#mermaid-svg-ip8qsfFO2ChiKEOC .edgeLabel span{color:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-ip8qsfFO2ChiKEOC .cluster text{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-ip8qsfFO2ChiKEOC .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-ip8qsfFO2ChiKEOC text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-ip8qsfFO2ChiKEOC .actor-line{stroke:grey}#mermaid-svg-ip8qsfFO2ChiKEOC .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-ip8qsfFO2ChiKEOC #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .sequenceNumber{fill:#fff}#mermaid-svg-ip8qsfFO2ChiKEOC #sequencenumber{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC #crosshead path{fill:#333;stroke:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .messageText{fill:#333;stroke:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-ip8qsfFO2ChiKEOC .labelText,#mermaid-svg-ip8qsfFO2ChiKEOC .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-ip8qsfFO2ChiKEOC .loopText,#mermaid-svg-ip8qsfFO2ChiKEOC .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-ip8qsfFO2ChiKEOC .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-ip8qsfFO2ChiKEOC .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-ip8qsfFO2ChiKEOC .noteText,#mermaid-svg-ip8qsfFO2ChiKEOC .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-ip8qsfFO2ChiKEOC .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-ip8qsfFO2ChiKEOC .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-ip8qsfFO2ChiKEOC .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-ip8qsfFO2ChiKEOC .mermaid-main-font{font-family:\”trebuchet ms\”, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC .section{stroke:none;opacity:0.2}#mermaid-svg-ip8qsfFO2ChiKEOC .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-ip8qsfFO2ChiKEOC .section2{fill:#fff400}#mermaid-svg-ip8qsfFO2ChiKEOC .section1,#mermaid-svg-ip8qsfFO2ChiKEOC .section3{fill:#fff;opacity:0.2}#mermaid-svg-ip8qsfFO2ChiKEOC .sectionTitle0{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .sectionTitle1{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .sectionTitle2{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .sectionTitle3{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-ip8qsfFO2ChiKEOC .grid .tick text{font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC .grid path{stroke-width:0}#mermaid-svg-ip8qsfFO2ChiKEOC .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-ip8qsfFO2ChiKEOC .task{stroke-width:2}#mermaid-svg-ip8qsfFO2ChiKEOC .taskText{text-anchor:middle;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC .taskText:not([font-size]){font-size:11px}#mermaid-svg-ip8qsfFO2ChiKEOC .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-ip8qsfFO2ChiKEOC .task.clickable{cursor:pointer}#mermaid-svg-ip8qsfFO2ChiKEOC .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-ip8qsfFO2ChiKEOC .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-ip8qsfFO2ChiKEOC .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-ip8qsfFO2ChiKEOC .taskText0,#mermaid-svg-ip8qsfFO2ChiKEOC .taskText1,#mermaid-svg-ip8qsfFO2ChiKEOC .taskText2,#mermaid-svg-ip8qsfFO2ChiKEOC .taskText3{fill:#fff}#mermaid-svg-ip8qsfFO2ChiKEOC .task0,#mermaid-svg-ip8qsfFO2ChiKEOC .task1,#mermaid-svg-ip8qsfFO2ChiKEOC .task2,#mermaid-svg-ip8qsfFO2ChiKEOC .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-ip8qsfFO2ChiKEOC .taskTextOutside0,#mermaid-svg-ip8qsfFO2ChiKEOC .taskTextOutside2{fill:#000}#mermaid-svg-ip8qsfFO2ChiKEOC .taskTextOutside1,#mermaid-svg-ip8qsfFO2ChiKEOC .taskTextOutside3{fill:#000}#mermaid-svg-ip8qsfFO2ChiKEOC .active0,#mermaid-svg-ip8qsfFO2ChiKEOC .active1,#mermaid-svg-ip8qsfFO2ChiKEOC .active2,#mermaid-svg-ip8qsfFO2ChiKEOC .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-ip8qsfFO2ChiKEOC .activeText0,#mermaid-svg-ip8qsfFO2ChiKEOC .activeText1,#mermaid-svg-ip8qsfFO2ChiKEOC .activeText2,#mermaid-svg-ip8qsfFO2ChiKEOC .activeText3{fill:#000 !important}#mermaid-svg-ip8qsfFO2ChiKEOC .done0,#mermaid-svg-ip8qsfFO2ChiKEOC .done1,#mermaid-svg-ip8qsfFO2ChiKEOC .done2,#mermaid-svg-ip8qsfFO2ChiKEOC .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-ip8qsfFO2ChiKEOC .doneText0,#mermaid-svg-ip8qsfFO2ChiKEOC .doneText1,#mermaid-svg-ip8qsfFO2ChiKEOC .doneText2,#mermaid-svg-ip8qsfFO2ChiKEOC .doneText3{fill:#000 !important}#mermaid-svg-ip8qsfFO2ChiKEOC .crit0,#mermaid-svg-ip8qsfFO2ChiKEOC .crit1,#mermaid-svg-ip8qsfFO2ChiKEOC .crit2,#mermaid-svg-ip8qsfFO2ChiKEOC .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-ip8qsfFO2ChiKEOC .activeCrit0,#mermaid-svg-ip8qsfFO2ChiKEOC .activeCrit1,#mermaid-svg-ip8qsfFO2ChiKEOC .activeCrit2,#mermaid-svg-ip8qsfFO2ChiKEOC .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-ip8qsfFO2ChiKEOC .doneCrit0,#mermaid-svg-ip8qsfFO2ChiKEOC .doneCrit1,#mermaid-svg-ip8qsfFO2ChiKEOC .doneCrit2,#mermaid-svg-ip8qsfFO2ChiKEOC .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-ip8qsfFO2ChiKEOC .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-ip8qsfFO2ChiKEOC .milestoneText{font-style:italic}#mermaid-svg-ip8qsfFO2ChiKEOC .doneCritText0,#mermaid-svg-ip8qsfFO2ChiKEOC .doneCritText1,#mermaid-svg-ip8qsfFO2ChiKEOC .doneCritText2,#mermaid-svg-ip8qsfFO2ChiKEOC .doneCritText3{fill:#000 !important}#mermaid-svg-ip8qsfFO2ChiKEOC .activeCritText0,#mermaid-svg-ip8qsfFO2ChiKEOC .activeCritText1,#mermaid-svg-ip8qsfFO2ChiKEOC .activeCritText2,#mermaid-svg-ip8qsfFO2ChiKEOC .activeCritText3{fill:#000 !important}#mermaid-svg-ip8qsfFO2ChiKEOC .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC g.classGroup text{fill:#9370db;stroke:none;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family);font-size:10px}#mermaid-svg-ip8qsfFO2ChiKEOC g.classGroup text .title{font-weight:bolder}#mermaid-svg-ip8qsfFO2ChiKEOC g.clickable{cursor:pointer}#mermaid-svg-ip8qsfFO2ChiKEOC g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-ip8qsfFO2ChiKEOC g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-ip8qsfFO2ChiKEOC .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-ip8qsfFO2ChiKEOC .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-ip8qsfFO2ChiKEOC .dashed-line{stroke-dasharray:3}#mermaid-svg-ip8qsfFO2ChiKEOC #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC .commit-id,#mermaid-svg-ip8qsfFO2ChiKEOC .commit-msg,#mermaid-svg-ip8qsfFO2ChiKEOC .branch-label{fill:lightgrey;color:lightgrey;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC .slice{font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-ip8qsfFO2ChiKEOC g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-ip8qsfFO2ChiKEOC g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-ip8qsfFO2ChiKEOC g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-ip8qsfFO2ChiKEOC .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-ip8qsfFO2ChiKEOC .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-ip8qsfFO2ChiKEOC .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-ip8qsfFO2ChiKEOC .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-ip8qsfFO2ChiKEOC .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-ip8qsfFO2ChiKEOC .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-ip8qsfFO2ChiKEOC .edgeLabel text{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-ip8qsfFO2ChiKEOC .node circle.state-start{fill:black;stroke:black}#mermaid-svg-ip8qsfFO2ChiKEOC .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-ip8qsfFO2ChiKEOC #statediagram-barbEnd{fill:#9370db}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-state .divider{stroke:#9370db}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-ip8qsfFO2ChiKEOC .note-edge{stroke-dasharray:5}#mermaid-svg-ip8qsfFO2ChiKEOC .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{–mermaid-font-family: \’\”trebuchet ms\”, verdana, arial\’;–mermaid-font-family: \”Comic Sans MS\”, \”Comic Sans\”, cursive}#mermaid-svg-ip8qsfFO2ChiKEOC .error-icon{fill:#522}#mermaid-svg-ip8qsfFO2ChiKEOC .error-text{fill:#522;stroke:#522}#mermaid-svg-ip8qsfFO2ChiKEOC .edge-thickness-normal{stroke-width:2px}#mermaid-svg-ip8qsfFO2ChiKEOC .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-ip8qsfFO2ChiKEOC .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-ip8qsfFO2ChiKEOC .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-ip8qsfFO2ChiKEOC .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-ip8qsfFO2ChiKEOC .marker{fill:#333}#mermaid-svg-ip8qsfFO2ChiKEOC .marker.cross{stroke:#333}

:root { –mermaid-font-family: \”trebuchet ms\”, verdana, arial;}
#mermaid-svg-ip8qsfFO2ChiKEOC {
color: rgba(0, 0, 0, 0.75);
font: ;
}

Subject

List<Observer> observers

+addObserver(Observer)

+removeObserver(Observer)

+notifyObservers(Object)

SubjectImpl

Object data

+change()

Observer

+update(Subject,Object)

ObserverImpl

+update(Subject,Object)

继承

继承

组成

依赖

在这里插入图片描述

实例

QCAD中,某一功能往往需要监听几何对象坐标的变化、选中状态的变化以及属性的变化等,来做出相应的处理。

Subject & Observer

RMainWidow作为被观察者。RCoordinateListener,RSelectionListener,RPropertyListener等等作为观察者。

class RMainWindow {
public:
    RMainWindow();
    virtual ~RMainWindow();

    void notifyListeners(bool withNull = false);

    void addCoordinateListener(RCoordinateListener* l);
    void removeCoordinateListener(RCoordinateListener* l);
    void notifyCoordinateListeners(RDocumentInterface* documentInterface);

    void addSelectionListener(RSelectionListener* l);
    void removeSelectionListener(RSelectionListener* l);
    void notifySelectionListeners(RDocumentInterface* documentInterface);

    void addPropertyListener(RPropertyListener* l);
    void removePropertyListener(RPropertyListener* l);
    void notifyPropertyListeners(
        RDocument* document,
        bool onlyChanges=false,
        RS::EntityType entityTypeFilter = RS::EntityUnknown
    );
    void notifyPropertyListeners(RDocument& document, REntity& entity);
    void notifyPropertyListeners();

    void addExportListener(RExportListener* l);
    void removeExportListener(RExportListener* l);
    void notifyExportListenersPre(RDocumentInterface* documentInterface);
    void notifyExportListenersPost(RDocumentInterface* documentInterface);
    void notifyExportListenersEnd(RExporter* exporter);

    void addEntityExportListener(REntityExportListener* l);
    void removeEntityExportListener(REntityExportListener* l);
    void notifyEntityExportListeners(RExporter* exporter, REntity* entity);

    void addImportListener(RImportListener* l);
    void removeImportListener(RImportListener* l);
    void notifyImportListenersPre(RDocumentInterface* documentInterface);
    void notifyImportListenersPost(RDocumentInterface* documentInterface);

    void addTransactionListener(RTransactionListener* l);
    void removeTransactionListener(RTransactionListener* l);
    void notifyTransactionListeners(RDocument* document, RTransaction* transaction = NULL);

    void addInterTransactionListener(RInterTransactionListener* l);
    void removeInterTransactionListener(RInterTransactionListener* l);
    void notifyInterTransactionListeners(RDocument* document, RTransaction* transaction = NULL);

    void addNewDocumentListener(RNewDocumentListener* l);
    void removeNewDocumentListener(RNewDocumentListener* l);
    void notifyNewDocumentListeners(RDocument* document, RTransaction* transaction, bool beforeLoad);

    void addSnapListener(RSnapListener* l);
    void removeSnapListener(RSnapListener* l);
    void notifySnapListeners(RDocumentInterface* documentInterface);

    void addFocusListener(RFocusListener* l);
    void removeFocusListener(RFocusListener* l);
    void notifyFocusListeners(RDocumentInterface* documentInterface);

    void addKeyListener(RKeyListener* l);
    void removeKeyListener(RKeyListener* l);
    void notifyKeyListeners(QKeyEvent* event);

    void addViewFocusListener(RViewFocusListener* l);
    void removeViewFocusListener(RViewFocusListener* l);
    void notifyViewFocusListeners(RGraphicsView* view);

    void addPreferencesListener(RPreferencesListener* l);
    void removePreferencesListener(RPreferencesListener* l);
    void notifyPreferencesListeners(RDocumentInterface* documentInterface);

    void propertyChangeEvent(RPropertyEvent& event);

    void addUcsListener(RUcsListener* l);
    void removeUcsListener(RUcsListener* l);
    void notifyUcsListeners(RDocumentInterface* documentInterface);

    void addLayerListener(RLayerListener* l);
    void removeLayerListener(RLayerListener* l);
    void notifyLayerListeners(RDocumentInterface* documentInterface, QList<RLayer::Id>& layerIds);
    void notifyLayerListenersCurrentLayer(RDocumentInterface* documentInterface, RLayer::Id previousLayerId);

    void addBlockListener(RBlockListener* l);
    void removeBlockListener(RBlockListener* l);
    void notifyBlockListeners(RDocumentInterface* documentInterface);
    void notifyBlockListenersCurrentBlock(RDocumentInterface* documentInterface);

    void addViewListener(RViewListener* l);
    void removeViewListener(RViewListener* l);
    void notifyViewListeners(RDocumentInterface* documentInterface);

    void addPenListener(RPenListener* l);
    void removePenListener(RPenListener* l);
    void notifyPenListeners(RDocumentInterface* documentInterface);

    void addPaletteListener(RPaletteListener* l);
    void removePaletteListener(RPaletteListener* l);
    void notifyPaletteListeners();

protected:

    QList<RCoordinateListener*> coordinateListeners;
    QList<RSelectionListener*> selectionListeners;
    QList<RPropertyListener*> propertyListeners;
    QList<RUcsListener*> ucsListeners;
    QList<RLayerListener*> layerListeners;
    QList<RBlockListener*> blockListeners;
    QList<RViewListener*> viewListeners;
    QList<RPenListener*> penListeners;
    QList<RPaletteListener*> paletteListeners;
    QList<REntityExportListener*> entityExportListeners;
    QList<RExportListener*> exportListeners;
    QList<RImportListener*> importListeners;
    QList<RTransactionListener*> transactionListeners;
    QList<RInterTransactionListener*> interTransactionListeners;
    QList<RNewDocumentListener*> newDocumentListeners;
    QList<RSnapListener*> snapListeners;
    QList<RKeyListener*> keyListeners;
    QList<RFocusListener*> focusListeners;
    QList<RViewFocusListener*> viewFocusListeners;
    QList<RPreferencesListener*> preferencesListeners;

};

坐标变化观察抽象类

class RCoordinateListener {
public:
    virtual ~RCoordinateListener() {}
    virtual void updateCoordinate(RDocumentInterface* documentInterface) = 0;
};

坐标变化观察实现类,当坐标发生变化时,发送信号。

class RCoordinateListenerAdapter: public QObject, public RCoordinateListener {
Q_OBJECT

public:
    RCoordinateListenerAdapter(QObject* parent=NULL) : QObject(parent) { }
    
    virtual ~RCoordinateListenerAdapter() { }

    virtual void updateCoordinate(RDocumentInterface* documentInterface) {
        emit coordinateUpdated(documentInterface);
    }

signals:
    void coordinateUpdated(RDocumentInterface* documentInterface);
};

被观察者发生变化,发出通知

bool RMainWindowQt::event(QEvent* e) {
    if (e==NULL) {
        return false;
    }
    ......
    ......
    ......
    RSelectionChangedEvent* sce = dynamic_cast<RSelectionChangedEvent*>(e);
    if (sce!=NULL) {
        // selection changed: reset property editor filter to show all entities:
        notifyPropertyListeners(getDocument(), false, RS::EntityAll);
        notifySelectionListeners(getDocumentInterface());
        return true;
    }

    RCoordinateEvent* coe = dynamic_cast<RCoordinateEvent*>(e);
    if (coe!=NULL) {
        RDocumentInterface* di = getDocumentInterface();
        if (di!=NULL) {
            di->coordinateEvent(*coe);
        }
        return true;
    }

    RTransactionEvent* te = dynamic_cast<RTransactionEvent*>(e);
    if (te!=NULL) {
        // combined properties might have changed (deleted entities):
        notifyPropertyListeners(getDocument(), te->hasOnlyChanges());
        // selection might have changed (deleted entities):
        notifySelectionListeners(getDocumentInterface());
        // notify transaction listeners:
        RTransaction t = te->getTransaction();
        notifyTransactionListeners(getDocument(), &t);
        return true;
    }

    RPropertyEvent* pe = dynamic_cast<RPropertyEvent*>(e);
    if (pe!=NULL) {
        RDocumentInterface* documentInterface = getDocumentInterface();
        if (documentInterface!=NULL) {
            documentInterface->propertyChangeEvent(*pe);
        }
    }

    RCloseCurrentEvent* cce = dynamic_cast<RCloseCurrentEvent*>(e);
    if (cce!=NULL) {
        if (mdiArea==NULL) {
            return true;
        }

        // workaround for QMdiArea bug: last window cannot be closed sometimes:
        if (mdiArea->activeSubWindow()==NULL) {
            QList<QMdiSubWindow *> subWindows = mdiArea->subWindowList();
            if (subWindows.size()==1) {
                //mdiArea->setActiveSubWindow(subWindows.at(0));
                qDebug() << "RMainWindowQt::event: closing subwindow";
                subWindows.at(0)->close();
            }
        }
        else {
            qDebug() << "RMainWindowQt::event: closing active subwindow";
            mdiArea->closeActiveSubWindow();
        }
        if (RSettings::getBoolValue("TabBar/ShowAddTabButton", false)) {
            mdiArea->updateTabBar();
        }
        return true;
    }
    ......
    ......
    ......
}

类图

csdn mermaid :

classDiagram

    RMainWindow<|--RMainWindowQt:继承

    RCoordinateListener<|--RCoordinateListenerAdapter:继承

    RMainWindow *--RCoordinateListener:组成

    RDocumentInterface<..RCoordinateListener:依赖

    RDocumentInterface -- RMainWindowQt

    class RMainWindow{
      - QList~RCoordinateListener*~ coordinateListeners
      + addCoordinateListener(RCoordinateListener*) void
      + removeCoordinateListener(RCoordinateListener* l) void
      + notifyCoordinateListeners(RDocumentInterface*) void
    }

    class RMainWindowQt{
      + event(QEvent) bool
    }
    class RCoordinateListener{
      + updateCoordinate(RDocumentInterface*) void
    }
    class RCoordinateListenerAdapter{
      + void updateCoordinate(RDocumentInterface*) void
    }

#mermaid-svg-WQ0OCK4ZAa195kor .label{font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family);fill:#333;color:#333}#mermaid-svg-WQ0OCK4ZAa195kor .label text{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor .node rect,#mermaid-svg-WQ0OCK4ZAa195kor .node circle,#mermaid-svg-WQ0OCK4ZAa195kor .node ellipse,#mermaid-svg-WQ0OCK4ZAa195kor .node polygon,#mermaid-svg-WQ0OCK4ZAa195kor .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-WQ0OCK4ZAa195kor .node .label{text-align:center;fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor .node.clickable{cursor:pointer}#mermaid-svg-WQ0OCK4ZAa195kor .arrowheadPath{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-WQ0OCK4ZAa195kor .flowchart-link{stroke:#333;fill:none}#mermaid-svg-WQ0OCK4ZAa195kor .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-WQ0OCK4ZAa195kor .edgeLabel rect{opacity:0.9}#mermaid-svg-WQ0OCK4ZAa195kor .edgeLabel span{color:#333}#mermaid-svg-WQ0OCK4ZAa195kor .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-WQ0OCK4ZAa195kor .cluster text{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-WQ0OCK4ZAa195kor .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-WQ0OCK4ZAa195kor text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-WQ0OCK4ZAa195kor .actor-line{stroke:grey}#mermaid-svg-WQ0OCK4ZAa195kor .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-WQ0OCK4ZAa195kor .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-WQ0OCK4ZAa195kor #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-WQ0OCK4ZAa195kor .sequenceNumber{fill:#fff}#mermaid-svg-WQ0OCK4ZAa195kor #sequencenumber{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor #crosshead path{fill:#333;stroke:#333}#mermaid-svg-WQ0OCK4ZAa195kor .messageText{fill:#333;stroke:#333}#mermaid-svg-WQ0OCK4ZAa195kor .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-WQ0OCK4ZAa195kor .labelText,#mermaid-svg-WQ0OCK4ZAa195kor .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-WQ0OCK4ZAa195kor .loopText,#mermaid-svg-WQ0OCK4ZAa195kor .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-WQ0OCK4ZAa195kor .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-WQ0OCK4ZAa195kor .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-WQ0OCK4ZAa195kor .noteText,#mermaid-svg-WQ0OCK4ZAa195kor .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-WQ0OCK4ZAa195kor .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-WQ0OCK4ZAa195kor .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-WQ0OCK4ZAa195kor .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-WQ0OCK4ZAa195kor .mermaid-main-font{font-family:\”trebuchet ms\”, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor .section{stroke:none;opacity:0.2}#mermaid-svg-WQ0OCK4ZAa195kor .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-WQ0OCK4ZAa195kor .section2{fill:#fff400}#mermaid-svg-WQ0OCK4ZAa195kor .section1,#mermaid-svg-WQ0OCK4ZAa195kor .section3{fill:#fff;opacity:0.2}#mermaid-svg-WQ0OCK4ZAa195kor .sectionTitle0{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor .sectionTitle1{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor .sectionTitle2{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor .sectionTitle3{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-WQ0OCK4ZAa195kor .grid .tick text{font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor .grid path{stroke-width:0}#mermaid-svg-WQ0OCK4ZAa195kor .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-WQ0OCK4ZAa195kor .task{stroke-width:2}#mermaid-svg-WQ0OCK4ZAa195kor .taskText{text-anchor:middle;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor .taskText:not([font-size]){font-size:11px}#mermaid-svg-WQ0OCK4ZAa195kor .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-WQ0OCK4ZAa195kor .task.clickable{cursor:pointer}#mermaid-svg-WQ0OCK4ZAa195kor .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WQ0OCK4ZAa195kor .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WQ0OCK4ZAa195kor .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WQ0OCK4ZAa195kor .taskText0,#mermaid-svg-WQ0OCK4ZAa195kor .taskText1,#mermaid-svg-WQ0OCK4ZAa195kor .taskText2,#mermaid-svg-WQ0OCK4ZAa195kor .taskText3{fill:#fff}#mermaid-svg-WQ0OCK4ZAa195kor .task0,#mermaid-svg-WQ0OCK4ZAa195kor .task1,#mermaid-svg-WQ0OCK4ZAa195kor .task2,#mermaid-svg-WQ0OCK4ZAa195kor .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-WQ0OCK4ZAa195kor .taskTextOutside0,#mermaid-svg-WQ0OCK4ZAa195kor .taskTextOutside2{fill:#000}#mermaid-svg-WQ0OCK4ZAa195kor .taskTextOutside1,#mermaid-svg-WQ0OCK4ZAa195kor .taskTextOutside3{fill:#000}#mermaid-svg-WQ0OCK4ZAa195kor .active0,#mermaid-svg-WQ0OCK4ZAa195kor .active1,#mermaid-svg-WQ0OCK4ZAa195kor .active2,#mermaid-svg-WQ0OCK4ZAa195kor .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-WQ0OCK4ZAa195kor .activeText0,#mermaid-svg-WQ0OCK4ZAa195kor .activeText1,#mermaid-svg-WQ0OCK4ZAa195kor .activeText2,#mermaid-svg-WQ0OCK4ZAa195kor .activeText3{fill:#000 !important}#mermaid-svg-WQ0OCK4ZAa195kor .done0,#mermaid-svg-WQ0OCK4ZAa195kor .done1,#mermaid-svg-WQ0OCK4ZAa195kor .done2,#mermaid-svg-WQ0OCK4ZAa195kor .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-WQ0OCK4ZAa195kor .doneText0,#mermaid-svg-WQ0OCK4ZAa195kor .doneText1,#mermaid-svg-WQ0OCK4ZAa195kor .doneText2,#mermaid-svg-WQ0OCK4ZAa195kor .doneText3{fill:#000 !important}#mermaid-svg-WQ0OCK4ZAa195kor .crit0,#mermaid-svg-WQ0OCK4ZAa195kor .crit1,#mermaid-svg-WQ0OCK4ZAa195kor .crit2,#mermaid-svg-WQ0OCK4ZAa195kor .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-WQ0OCK4ZAa195kor .activeCrit0,#mermaid-svg-WQ0OCK4ZAa195kor .activeCrit1,#mermaid-svg-WQ0OCK4ZAa195kor .activeCrit2,#mermaid-svg-WQ0OCK4ZAa195kor .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-WQ0OCK4ZAa195kor .doneCrit0,#mermaid-svg-WQ0OCK4ZAa195kor .doneCrit1,#mermaid-svg-WQ0OCK4ZAa195kor .doneCrit2,#mermaid-svg-WQ0OCK4ZAa195kor .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-WQ0OCK4ZAa195kor .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-WQ0OCK4ZAa195kor .milestoneText{font-style:italic}#mermaid-svg-WQ0OCK4ZAa195kor .doneCritText0,#mermaid-svg-WQ0OCK4ZAa195kor .doneCritText1,#mermaid-svg-WQ0OCK4ZAa195kor .doneCritText2,#mermaid-svg-WQ0OCK4ZAa195kor .doneCritText3{fill:#000 !important}#mermaid-svg-WQ0OCK4ZAa195kor .activeCritText0,#mermaid-svg-WQ0OCK4ZAa195kor .activeCritText1,#mermaid-svg-WQ0OCK4ZAa195kor .activeCritText2,#mermaid-svg-WQ0OCK4ZAa195kor .activeCritText3{fill:#000 !important}#mermaid-svg-WQ0OCK4ZAa195kor .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor g.classGroup text{fill:#9370db;stroke:none;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family);font-size:10px}#mermaid-svg-WQ0OCK4ZAa195kor g.classGroup text .title{font-weight:bolder}#mermaid-svg-WQ0OCK4ZAa195kor g.clickable{cursor:pointer}#mermaid-svg-WQ0OCK4ZAa195kor g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-WQ0OCK4ZAa195kor g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-WQ0OCK4ZAa195kor .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-WQ0OCK4ZAa195kor .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-WQ0OCK4ZAa195kor .dashed-line{stroke-dasharray:3}#mermaid-svg-WQ0OCK4ZAa195kor #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor .commit-id,#mermaid-svg-WQ0OCK4ZAa195kor .commit-msg,#mermaid-svg-WQ0OCK4ZAa195kor .branch-label{fill:lightgrey;color:lightgrey;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor .slice{font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-WQ0OCK4ZAa195kor g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-WQ0OCK4ZAa195kor g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-WQ0OCK4ZAa195kor g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-WQ0OCK4ZAa195kor .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-WQ0OCK4ZAa195kor .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-WQ0OCK4ZAa195kor .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-WQ0OCK4ZAa195kor .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-WQ0OCK4ZAa195kor .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-WQ0OCK4ZAa195kor .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-WQ0OCK4ZAa195kor .edgeLabel text{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:\’trebuchet ms\’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-WQ0OCK4ZAa195kor .node circle.state-start{fill:black;stroke:black}#mermaid-svg-WQ0OCK4ZAa195kor .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-WQ0OCK4ZAa195kor #statediagram-barbEnd{fill:#9370db}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-state .divider{stroke:#9370db}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-WQ0OCK4ZAa195kor .note-edge{stroke-dasharray:5}#mermaid-svg-WQ0OCK4ZAa195kor .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{–mermaid-font-family: \’\”trebuchet ms\”, verdana, arial\’;–mermaid-font-family: \”Comic Sans MS\”, \”Comic Sans\”, cursive}#mermaid-svg-WQ0OCK4ZAa195kor .error-icon{fill:#522}#mermaid-svg-WQ0OCK4ZAa195kor .error-text{fill:#522;stroke:#522}#mermaid-svg-WQ0OCK4ZAa195kor .edge-thickness-normal{stroke-width:2px}#mermaid-svg-WQ0OCK4ZAa195kor .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-WQ0OCK4ZAa195kor .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-WQ0OCK4ZAa195kor .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-WQ0OCK4ZAa195kor .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-WQ0OCK4ZAa195kor .marker{fill:#333}#mermaid-svg-WQ0OCK4ZAa195kor .marker.cross{stroke:#333}

:root { –mermaid-font-family: \”trebuchet ms\”, verdana, arial;}
#mermaid-svg-WQ0OCK4ZAa195kor {
color: rgba(0, 0, 0, 0.75);
font: ;
}

RMainWindow

– QList<RCoordinateListener*> coordinateListeners

+addCoordinateListener(RCoordinateListener*)

+removeCoordinateListener(RCoordinateListener* l)

+notifyCoordinateListeners(RDocumentInterface*)

RMainWindowQt

+event(QEvent)

RCoordinateListener

+updateCoordinate(RDocumentInterface*)

RCoordinateListenerAdapter

void updateCoordinate

RDocumentInterface

继承

继承

组成

依赖

在这里插入图片描述

Usage

监控图层的变化。

var appWin = EAction.getMainWindow();
var adapter = new RLayerListenerAdapter();
appWin.addLayerListener(adapter);
adapter.layersUpdated.connect(function(documentInterface, previousLayerId){
    var doc = documentInterface.getDocument();
    var result = doc.queryAllLayers();
    for ( var i = 0; i < result.length; ++i) {
        var id = result[i];
        layer = doc.queryLayer(id);
        if (layer.isNull()) {
            continue;
        }
        qDebug(i+",LayerName:"+layer.getName());
    }
});

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享