make_later()¶
Declare a widget field that will be initialized later, typically in the setup() lifecycle hook.
Overview¶
make_later() is used when you need to initialize a field after the widget is constructed, usually because:
- The field depends on other fields that need to be initialized first
- You need to reference
selfduring initialization - The field requires complex initialization logic
Signature¶
Returns a dataclass field that is excluded from __init__ and must be set manually.
Basic Usage¶
Simple Deferred Field¶
from qtpie import widget, make_later
@widget()
class MyWidget(QWidget):
value: int = make_later()
def setup(self) -> None:
self.value = 42
The field is uninitialized until you set it in setup().
Common Use Case: Secondary ObservableProxy¶
Note: For Widget[T] classes, QtPie automatically creates model and record_observable_proxy - you don't need make_later() for the default case.
Use make_later() when you need a secondary proxy for a different model:
from dataclasses import dataclass
from observant import ObservableProxy
from qtpie import Widget, make, make_later, widget
from qtpy.QtWidgets import QLineEdit, QWidget
@dataclass
class Dog:
name: str = ""
@dataclass
class Owner:
name: str = ""
@widget()
class DogEditor(QWidget, Widget[Dog]):
# model and record_observable_proxy for Dog are auto-created
name_edit: QLineEdit = make(QLineEdit, bind="name") # binds to Dog
# Secondary model needs make_later() for its proxy
owner_model: Owner = make(Owner)
owner_proxy: ObservableProxy[Owner] = make_later()
owner_edit: QLineEdit = make(QLineEdit, bind="owner_proxy.name")
def setup(self) -> None:
self.owner_proxy = ObservableProxy(self.owner_model, sync=True)
Why use make_later() here?
- The owner_proxy needs to wrap the owner_model object
- But owner_model doesn't exist yet during field initialization
- So we defer owner_proxy creation until setup() when owner_model is available
Widget[T] with make_later()¶
When using Widget[T], you can defer model initialization:
@widget()
class PersonEditor(QWidget, Widget[Person]):
record: Person = make_later() # Will be set in setup()
name: QLineEdit = make(QLineEdit)
def setup(self) -> None:
# Custom model initialization
self.record = Person(name="Charlie", age=25)
Error Handling¶
If you use make_later() for the model but forget to set it in setup(), QtPie will raise a helpful error:
@widget()
class PersonEditor(QWidget, Widget[Person]):
record: Person = make_later()
name: QLineEdit = make(QLineEdit)
# Oops! No setup() method
# Raises: ValueError: Field 'model' marked with make_later() was not set in setup()
w = PersonEditor()
This prevents silent failures when you accidentally omit initialization.
Multiple Deferred Fields¶
You can use make_later() for multiple secondary proxies:
from dataclasses import dataclass
from observant import ObservableProxy
from qtpie import Widget, make, make_later, widget
from qtpy.QtWidgets import QLineEdit, QWidget
@dataclass
class Dog:
name: str = ""
@dataclass
class Cat:
name: str = ""
@widget()
class PetEditor(QWidget, Widget[Dog]):
# Dog's model/record_observable_proxy are auto-created
dog_name: QLineEdit = make(QLineEdit, bind="name") # binds to Dog
# Cat needs manual proxy setup
cat_model: Cat = make(Cat)
cat_proxy: ObservableProxy[Cat] = make_later()
cat_name: QLineEdit = make(QLineEdit, bind="cat_proxy.name")
def setup(self) -> None:
self.cat_proxy = ObservableProxy(self.cat_model, sync=True)
When to Use make_later()¶
Use make_later() when:
- Field initialization depends on other fields
- You need to reference self during initialization
- You want to defer complex setup logic to setup()
Don't use make_later() when:
- The field can be initialized independently → Use make() instead
- You're just creating a simple widget → Use make() instead
Comparison: make() vs make_later()¶
# ✓ Use make() - field is independent
label: QLabel = make(QLabel, "Hello")
# ✓ Use make() - simple default value
model: Dog = make(Dog)
# ✓ Use make_later() - depends on model field
proxy: ObservableProxy[Dog] = make_later()
# ✗ DON'T use make_later() unnecessarily
label: QLabel = make_later() # Just use make()!
Implementation Details¶
Under the hood, make_later() creates a dataclass field with:
- init=False - excluded from __init__
- Special metadata flag for QtPie tracking
Lifecycle Flow¶
@widget()
class Example(QWidget):
regular: QLabel = make(QLabel, "I'm created first")
deferred: int = make_later()
def setup(self) -> None:
# Called after regular fields are initialized
self.deferred = 42
# Execution order:
# 1. __init__() creates 'regular' field
# 2. setup() runs → 'deferred' gets set
# 3. Widget is ready
See Also¶
- make() - Standard widget factory
- Widget Lifecycle - When
setup()is called - Widget[T] - Model widget base class
- Data Binding - Binding widgets to data
Tips¶
- Always set deferred fields in setup()
- QtPie will error if you forget (for Widget[T] models)
-
Your code will error at runtime for other fields
-
Use for ObservableProxy pattern
- This is the #1 use case
-
Model → make(), Proxy → make_later()
-
Keep it simple
- If you can use
make(), use it - Only defer when truly necessary