防止“继承"信号处理程序执行 [英] Prevent "inherited" signal handlers from executing

查看:103
本文介绍了防止“继承"信号处理程序执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当许多派生组件将频繁使用该功能时,在基本"组件中定义信号处理程序是非常不错的选择.

Defining a signal handler in a "base" component is pretty nifty when that functionality is going to be frequently used by many derived components.

但是,在QML中,在派生组件中安装新处理程序不会替换原始处理程序,它只是堆叠在其顶部.由于处理程序并不是每个信号真正唯一,因此它们仅仅是连接,每个信号可以有多个连接.

However, in QML installing a new handler in a derived component does not replace the original handler, it merely stacks on top of it. As handlers are not really unique per signal, they are merely connections, and you can have multiple connections per signal.

一种解决方案是根本不在基本组件中提供默认处理程序,但是每次使用组件时,您都必须复制并粘贴该处理程序.那有更好的方法吗?

One solution is to simply not provide a default handler in the base component, but then you have to copy and paste the handler each and every time a component is used. So is there a better way?

推荐答案

如peppe所述,一种解决方案是代替直接安装处理程序,只需使处理程序成为对可以覆盖的函数的调用即可.但是,如果要在派生的组件中重用基础实现,而不必在具有组件继承的顺序处理程序堆栈中重用,则函数重写本身就是一个混合包.

As peppe mentioned, one solution would be to instead of installing the handler directly, just make the handler a call to a function that can be overriden. However, function overriding itself is a mixed bag, when there is intent to reuse base implementations in the derived components, not necessarily in the order handlers stack with component inheritance.

我实际上想出了一个灵活的解决方案,尽管有点笨拙.它是要手动断开先前安装的处理程序并手动连接一个新的处理程序.这有两个含义:

I actually came up with a flexible, albeit a little clunky solution. It is to manually disconnect the previous installed handler and manually connect a new one. This has two implications:

  1. 处理程序不能是匿名表达式,它们必须实现为函数,以便可以引用以断开连接.

  1. The handlers cannot be anonymous expressions, they have to implemented as functions so they can be referenced for disconnect.

不能使用声明性语法(onSignal: handler())绑定处理程序,因为它不连接到处理程序函数,而是连接到调用处理程序函数的匿名表达式.这样就无法断开连接.

The handlers cannot be bound using the declarative syntax (onSignal: handler()), as this doesn't connect to the handler function, but to an anonymous expression which invokes the handler function. So you can't disconnect.

所以看起来像这样:

//BaseComp.qml
QtObject {
    signal sig(int i)
    function baseHandler(i) {...}
    Component.onCompleted: sig.connect(baseHandler)
}

//DerivedComp.qml
BaseComp {
    function derivedHandler(i) {...}
    Component.onCompleted: {
        sig.disconnect(baseHandler)
        sig.connect(derivedHandler)
    }
}

基本模式是在每个覆盖它的派生组件中断开先前的基本处理程序.这样,如果需要,您可以从派生的组件访问基本处理程序,如果只有一个重写的处理程序功能,则由于无法实现派生类中的重写,因此无法从派生类访问基本实现. QML(将有两个名称相同的函数作为对象的成员,但它们两个都将引用派生的组件替代).

The basic pattern is disconnect the previous base handler in every derived component which overrides it. This way you get to access the base handlers from the derived components if there is a need to do that, if instead there is only one overridden handler function, the base implementations will not be accessible from the derived classes due to how overriding is implemented in QML (there will be two identically named functions as members of the object, but both of them will refer to the derived component override).

如果QML提供了一种制作唯一"绑定的漂亮方法,那将是非常有用和有用的-在创建新的绑定之前,该绑定会清除以前的所有连接.然后,不需要所有这些解决方法代码.

It would be niceand useful if QML provided a pretty way to make a "unique" binding - something that purges all previous connections before making the new one. Then all that workaround code would not be needed.

这篇关于防止“继承"信号处理程序执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆