用vc2005 MFC实现的根据TreeCtrl动态生成TabCtrl 控件TAB页的例子代码

例子中基于MFC单文档视图,实现了点击TreeCtrl的不同子ITEM动态生成TabCtrl控件相应TAB页功能,如果一些TAB页已经生成,点击相应的TreeCtrl子ITEM则切换到已生成的TAB页上,支持TAB页右键菜单关闭,左键双击关闭功能。

文件:n459.com/file/25127180-479632636 访问密码:551685

以下内容无关:

-------------------------------------------分割线---------------------------------------------

大家好,我们今天来了解一个新的设计模式——观察者模式。

观察者模式的思路很简单,它被广泛地用在各种数据监控上。很多时候我们希望监听某个数据的变化,希望一旦获悉它的变化之后立即采取一些举措。按照常规的操作,我们需要开启额外的线程来进行监听。但是开启线程一则非常麻烦,二则需要带来额外的开销,我们今天介绍的观察者模式就可以在无需多余开销的基础上完成这个功能。

观察者
在观察者模式当中,整个运行流和常规的操作相反,我们并不是用一些程序去监听数据的变化。相反而是当数据发生变化的时候,我们去通知对应的监听器数据产生了变化。好处我们前面也说过了,可以避免多余的开销。

首先,我们来实现两个监听器。也就是当数据发生变化之后会触发这两个监听器。在这个设计模式当中,监听器被命名为viewer,这里的观察不是一种主动的观察而是一种被动地接收通知。也许是起名的人想不出更好的名字来吧,其实我觉得应该叫做receiver更好。

class IncreaseViewer:

def __init__(self):
    self.data = 0

def update(self, subject):
    # 判断是否增加
    if subject.data > self.data:
        print('Increased: Subject {} data increased to {}'.format(subject.name, subject.data))
        self.data = subject.data

class DeclineViewer:

def __init__(self):
    self.data = 0

def update(self, subject):
    # 判断是否减少
    if subject.data < self.data:
    print('Decreased: Subject %s data decreased to %d' % (subject.name, subject.data))
    self.data = subject.data

数据
观察者的代码应该很好理解,理解了观察者类之后,我们再来看看数据类。

数据的类其实也很简单,我们只需要设计一个功能,让它可以在数据发生赋值操作的时候去通知一下观察者就可以了。我们都知道在Python当中,赋值操作是没办法直接感知的,但是类当中的成员发生变化的时候,我们是可以通过@property装饰器来进行修饰的。

所以我们就利用这一点来实现数据这个类,如果大家熟悉@property注解的话,也非常简单。

class Data(Subject):

def __init__(self, name=''):
    Subject.__init__(self)
    self.name = name
    self._data = 0

@property
def data(self):
    return self._data

@data.setter
def data(self, data):
    self._data = data
    # 关键
    self.notify()

大家看到了data这个方法当中的self.notify了吗?这个就是通知函数,所以就是当Data这个类当中的data成员发生变化的时候,我们执行通知操作,去通知观察者执行。

管理观察者
现在我们观察者实现好了,数据类也有了,剩下的就是把这两者连通起来了。我们当然也可以简单粗暴地用代码实现,但是比较好的做法是对数据和观察者之间的联系做一个简单的管理。因为可能不同的数据需要的观察者不一样,我们并不能简单粗暴地一概而论。

其实管理观察者也不需要太复杂,只需要用面向对象的思路对list进行一个简单的封装即可。

class Subject:

def __init__(self):
    self._observer = []

def attach(self, observer):
    if observer not in self._observer:
        self._observer.append(observer)

def detach(self, observer):
    try:
        self._observer.remove(observer)
    except ValueError:
        pass

def notify(self, modifier=None):
    for observer in self._observer:
        if modifier != observer:
            observer.update(self)

attach表示关联,也就是给数据关联上观察者,detach表示解除关联,notify自然就是通知了。其实也就是用一个循环遍历一下所有的观察者,然后执行一下对应的update函数就可以了。

这里为了简化逻辑,我们把Subject类做成了Data类的父类。这样某种程度上相当于解耦了观察者和数据,我们以后无论是对哪部分逻辑进行修改或者是优化都不会影响另外两方。整个代码不过50行,可以说是非常简便了,不仅是Python,对于其他支出多态的语言来说,这个设计模式也是同样适用的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Treectrl 是一个在文件目录中显示文件和文件夹结构的控件,它在 C 语言中也有相应的应用示例。 假设我们有一个文件目录的结构如下: - 文件夹A - 文件1.txt - 文件2.txt - 文件夹B - 文件3.txt - 文件夹C - 文件4.txt 现在我们想在应用程序中使用 Treectrl 控件来显示上述文件目录。首先,我们需要创建一个 Treectrl 控件,可以使用创建窗口的相关函数来实现。然后,我们将通过添加节点的方式来构建文件目录结构。 在 C 语言中,可以使用 Treectrl 相关的 API 函数来操作和管理控件。例如,可以使用插入节点函数 `TreeInsertItem` 来添加文件夹和文件节点。我们可以通过提供节点的文本、图标和父节点等信息来插入节点。 对于上述文件目录结构的例子,我们可以首先插入文件夹 A 的节点,并将其作为树的根节点。然后,将文件 1.txt 和文件 2.txt 分别插入到文件夹 A 的子节点中。接着,创建文件夹 B 的节点,并将文件 3.txt 插入到文件夹 B 的子节点中。最后,再创建文件夹 C 的节点,并将文件 4.txt 插入到文件夹 C 的子节点中。 通过这样的操作,我们就可以使用 Treectrl 控件来显示文件目录结构了。当用户展开或折叠文件夹节点时,我们可以根据需要动态加载和更新子节点。 总之,Treectrl 控件在 C 语言中提供了一种简单方便的方式来显示文件目录结构。我们可以通过添加、删除、展开、折叠节点等操作以及相关的事件处理来实现对文件目录的交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值