When to use the trait Instance() constructor, and questions about the traitsUI tutorial code

StackOverflow https://stackoverflow.com/questions/18716433

  •  28-06-2022
  •  | 
  •  

Question

I have a question regarding the traitsui tutorial by Gael Varoquaux. In code snippet 7 he makes a CaptureThread class for producing a thread for taking images from a camera. He also make a Camera class.

class TextDisplay(HasTraits):
    string = String()
    view = View(Item('string', show_label=False, springy=True, style='custom'))

class CaptureThread(Thread):
    def run(self):
        #self.display is set outside the class definition by the caller
        self.display.string = 'Camera started\n' + self.display.string
        n_img = 0
        while not self.wants_abort:
            sleep(0.5)
            n_img += 1
            self.display.string = ' %d image captured\n' % n_img \
                                        + self.display.string
        self.display.string = 'Camera stopped\n' + self.display.string

class Camera(HasTraits):
    start_stop_capture = Button()
    display = Instance(TextDisplay)
    capture_thread = Instance(CaptureThread)

    view = View( Item('start_stop_capture', show_label=False))

    def _start_stop_capture_fired(self):
        if self.capture_thread and self.capture_thread.isAlive():
            self.capture_thread.wants_abort = True
        else:
            self.capture_thread = CaptureThread()
            self.capture_thread.wants_abort = False
            self.capture_thread.display = self.display
            self.capture_thread.start()

I have two questions about this code:

1) Why in the Camera class definition does he make capture_thread a Trait, by calling Instance(CaptureThread)? CaptureThread is just a thread class, why should we make a trait instance out of it?

2) In the CaptureThread class he makes use of a field self.display.string and of self.wants_abort. These two fields are not passed in via a constructor method, rather they are assigned outside of the class definition by the Camera class. Is this the best practise? Since if the user of the CaptureThread forgot to set these two fields, then an error would occur. Are there some sensible guidelines to know when I can assign thing like that, or I should use a constructor to assign them?

I hope that these questions make sense, and that this is the right place to ask them! Thanks, labjunky

Was it helpful?

Solution

  1. capture_thread = Instance(CaptureThread) doesn't make an instance of CaptureThread. It is more of a declaration that gets consumed by the Camera class when the class gets created. It tells that Camera class that it will have an attribute named capture_thread that should be an instance of CaptureThread or None and will default to None. This default lets the "test if self.capture_thread is initialized, otherwise create it" logic in _start_stop_capture_fired() a little cleaner, at least to some people's tastes.

  2. For threading.Thread subclasses, yes, it's one idiomatic way to do it, though not the only one. Thread already has a specific __init__ implementation, and you could override it to do something else, but it is understandable that the author would avoid doing so in this case.

    This is not the idiomatic way to initialize HasTraits subclasses which is indeed to use keyword arguments.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top