New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Listen to a field change in a sibling magicclass #129
Comments
I think you can just define the callback in the parent class. from magicclass import magicclass, vfield
@magicclass
class A:
@magicclass
class B:
b = vfield(int)
@magicclass
class C:
pass
@B.b.connect
def _on_b_change(self, value):
print(self.C, value)
ui = A()
ui.show() Do you think this works for your case? |
This mostly works, although my nested magicclasses are mostly inside |
Is this example similar to your case? from magicclass import magicclass, field
@magicclass
class A:
x = field(int)
@magicclass
class Main:
a = field(A)
# A.x is not accessible here
ui = Main()
ui.show() |
Yes basically. I have @magicclass
class A:
x = field(int)
@magicclass
class Main:
a = vfield(A)
# This works
@a.connect()
def _on_a_changed():
...
# This doesn't work
@a.x.connect()
def _on_x_changed():
... |
I got it. 1. Define a field in the parent.Since last release, from magicclass import magicclass, field, abstractapi
@magicclass
class A:
x = abstractapi()
@magicclass
class Main:
a = field(A)
x = field(int, location=A)
@x.connect
def _on_x_changed(self):
print(self, "on x changed")
ui = Main()
ui.show() 2. Use
|
Thanks, but how can I now put these ideas together to listen to a sibling's event? I can move the field into the parent using @magicclass
class A:
x = field(int)
@magicclass
class B:
# How to implement this?
def on_x_changed(...): ...
@magicclass
class Main:
a = vfield(A)
b = vfield(B) |
In that case you'll have to rely on @magicclass
class A:
x = field(int)
@x.connect
def _on_x_changed(self):
self.find_ancestor(Main).b._on_x_changed()
@magicclass
class B:
def _on_x_changed(self):
print(self)
@magicclass
class Main:
a = vfield(A)
b = vfield(B)
ui = Main()
ui.show() Regarding to #110, can you check if directly nesting magicclasses works? @magicclass
class Main:
@magicclass
class A:
x = field(int)
@magicclass
class B:
pass
@A.x.connect
def _do_something_in_b(self):
print(self.B) Magic classes treat child magic classes differently from other simple widgets. You may not have to hide classes in fields if not needed. |
Thanks. I've already tried removing the |
I wonder if it would be helpful to allow child classes to listen to parent events in some way. Because if this were possible then I could decouple everything properly: the first child class being changed could fire an event which the parent captures and then it triggers its own event which the other is connected to. |
Can you show me how you put
You can still manually connect signals in the top-level class as below. from magicclass import magicclass, field, vfield
@magicclass
class A:
x = field(int)
@magicclass
class B:
def _on_x_changed(self):
print(self)
@magicclass
class Main:
a = vfield(A)
b = vfield(B)
def __post_init__(self):
# signal connection(s).
self.a.x.changed.connect(self.b._on_x_changed)
ui = Main()
ui.show() However, I don't think it's a good idea to connect parent events to all the children by default. It means that any event in the parent class has to be recursively passed to all its offsprings, which causes very bad performance for complicated widgets. The |
If I have classes like this:
How can I implement
on_b_change
so that it will trigger whenB.b
actually changes? I don't think that@wraps
works here, but I could be wrong. Also I tried using__magicclass_parent__
in the__post_init__
to search up the tree for the field, but the parent relationship doesn't seem to exist at that point.The text was updated successfully, but these errors were encountered: