Qt:有关信号/槽的样式

发布于 2024-12-22 16:18:45 字数 419 浏览 6 评论 0 原文

我有一个对象 X,它拥有(拥有指向并初始化)对象 Y1..10

对象 X 的状态会不时变化。 我希望子对象(Y1..10)能够意识到状态。

通常,这可以通过从每个 Y 子对象指向父 X 的指针来解决,以便它可以通过方法调用查询其状态,但我不希望 Y 对象知道对象 X,只知道它的状态。

我想知道这是否可以通过信号/插槽来实现:

Y 对象将定义一个信号,例如:

void GetStatus(TheStatus & status);

X 对象会将其连接到插槽,当由 Y 对象发出时,对象 X 会将状态写入状态给出引用以便 Y 对象获取它。

通过这种方式,我可以为 Y 对象提供可用的状态更新,但它们不需要了解对象 X 即可实现这一点。

你怎么认为?

I have an Object X which owns (owns pointers to and initializes) Objects Y1..10

Object X has a state that changes from time to time.
I'd like the child objects (Y1..10) to become aware of the state.

Typically, this is resolvable by having a pointer to the parent X from each Y child object, so that it can query its status via a method call, but I don't want the Y objects to be aware of object X, just its status.

I was wondering if this could be implemented with signals/slots:

The Y objects will define a signal such as:

void GetStatus(TheStatus & status);

The X object will connect this to a slot, and when emitted by a Y object, object X will write the status onto the status reference given so that the Y object gets it.

This way I can have status updates be available for Y objects, and yet, they do not need to be aware of object X to achieve that.

What do you think?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅唱ヾ落雨殇 2024-12-29 16:18:45

看来你是在倒着想。如果 X 对象是想要执行“通知”的对象,那么它应该发出信号。那么 Y 对象将有槽作为“接收器”。

所以 X 对象应该发出一个信号,例如:

void X::statusChanged(TheStatus status);

那么 Y 对象将有某种匹配的槽。假设适当的私有/公共权限,任何对象(可能是 Z 甚至 X 和 Y 本身)都可以使用 QObject::connect 调用将对象实例的匹配信号和槽绑定在一起。您甚至可以将信号与信号联系起来。

虽然您可以将 Y 中的该槽称为 onStatusChanged 之类的名称,但这表明您的设计中的耦合有点过于紧密。毕竟,槽可以像常规方法一样被调用。因此,如果您能想到插槽实际上的作用,而不是根据其调用者来命名它,那可能会更明智。

(如果一个函数 foo() 调用另一个函数,我们倾向于根据它的功能给它一个新名称 bar(),而不是 theFunctionCalledByFoo(),对吧?)

正如 Martin 指出的那样,最好尝试保持插槽使用的类型相当基本并按值发送它们。如果您发送指针和引用,那么您就会担心对象的生命周期,特别是在信号/槽在队列中处理的多线程场景中。

一个易于理解的基于通知的类的一个很好的例子可能是进度条:

http://developer.qt.nokia.com/doc/qt-4.8/qprogressbar.html#details

It looks like you are thinking of it backwards. If the X object is the one that wants to do the "notifying", then it should be emitting the signal. Then the Y objects would have the slot to be the "receivers".

So X object should be emitting a signal, like:

void X::statusChanged(TheStatus status);

Then the Y object would have some kind of matching slot. Assuming proper private/public privileges, any object—perhaps Z or even X and Y themselves—could use the QObject::connect call to tie together matching signals and slots of object instances together. You can even tie signals to signals.

While it's possible that you could call that slot in Y something like onStatusChanged, that suggests a little too tight a coupling in your design. After all, a slot can be called just like a regular method. So if you can think of what the slot actually does rather than naming it on the basis of its caller, that can be more sensible.

(If a function foo() calls another function, we tend to give that a new name bar() based on what it does, instead of theFunctionCalledByFoo(), right?)

It's preferable as Martin pointed out to try and keep the types that slots use fairly basic and send them by value. If you send pointers and references then you get into worries about object lifetimes, especially in multithreaded scenarios where the signals/slots are processed in a queue.

A good example of a notification-based class to play with that's simple to understand might be the progress bar:

http://developer.qt.nokia.com/doc/qt-4.8/qprogressbar.html#details

林空鹿饮溪 2024-12-29 16:18:45

这正是信号/槽的用途。

任意数量的孩子都可以订阅信号,而发送代码不需要知道他们,发送者甚至不需要有任何信号接收者。

一般来说,我尝试保持信号/槽发送的值简单而不是复杂的对象 - 这样更容易单独进行更改。

That's exactly what signals/slots are for.

Any number of children can subscribe to a signal without the sending code needing to be aware of them, the sender doesn't even need there to be any receivers for it's signal.

In general I try and keep the values sent by signals/slots simple rather than complex objects - that way it's easier to make changes separately.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文