How would you design a very “Pythonic” UI framework?

后端 未结 15 1797
日久生厌
日久生厌 2021-02-02 01:29

I have been playing with the Ruby library \"shoes\". Basically you can write a GUI application in the following way:

Shoes.app do
  t = para \"Not clicked!\"
  b         


        
相关标签:
15条回答
  • 2021-02-02 01:49

    This is extremely contrived and not pythonic at all, but here's my attempt at a semi-literal translation using the new "with" statement.

    with Shoes():
      t = Para("Not clicked!")
      with Button("The Label"):
        Alert("You clicked the button!")
        t.replace("Clicked!")
    

    The hardest part is dealing with the fact that python will not give us anonymous functions with more than one statement in them. To get around that, we could create a list of commands and run through those...

    Anyway, here's the backend code I ran this with:

    context = None
    
    class Nestable(object):
      def __init__(self,caption=None):
        self.caption = caption
        self.things = []
    
        global context
        if context:
          context.add(self)
    
      def __enter__(self):
        global context
        self.parent = context
        context = self
    
      def __exit__(self, type, value, traceback):
        global context
        context = self.parent
    
      def add(self,thing):
        self.things.append(thing)
        print "Adding a %s to %s" % (thing,self)
    
      def __str__(self):
        return "%s(%s)" % (self.__class__.__name__, self.caption)
    
    
    class Shoes(Nestable):
      pass
    
    class Button(Nestable):
      pass
    
    class Alert(Nestable):
      pass
    
    class Para(Nestable):
      def replace(self,caption):
        Command(self,"replace",caption)
    
    class Command(Nestable):
      def __init__(self, target, command, caption):
        self.command = command
        self.target  = target
        Nestable.__init__(self,caption)
    
      def __str__(self):
        return "Command(%s text of %s with \"%s\")" % (self.command, self.target, self.caption)
    
      def execute(self):
        self.target.caption = self.caption
    
    0 讨论(0)
  • 2021-02-02 01:49

    If you use PyGTK with glade and this glade wrapper, then PyGTK actually becomes somewhat pythonic. A little at least.

    Basically, you create the GUI layout in Glade. You also specify event callbacks in glade. Then you write a class for your window like this:

    class MyWindow(GladeWrapper):
        GladeWrapper.__init__(self, "my_glade_file.xml", "mainWindow")
        self.GtkWindow.show()
    
        def button_click_event (self, *args):
            self.button1.set_label("CLICKED")
    

    Here, I'm assuming that I have a GTK Button somewhere called button1 and that I specified button_click_event as the clicked callback. The glade wrapper takes a lot of effort out of event mapping.

    If I were to design a Pythonic GUI library, I would support something similar, to aid rapid development. The only difference is that I would ensure that the widgets have a more pythonic interface too. The current PyGTK classes seem very C to me, except that I use foo.bar(...) instead of bar(foo, ...) though I'm not sure exactly what I'd do differently. Probably allow for a Django models style declarative means of specifying widgets and events in code and allowing you to access data though iterators (where it makes sense, eg widget lists perhaps), though I haven't really thought about it.

    0 讨论(0)
  • 2021-02-02 01:52

    Personally, I would try to implement JQuery like API in a GUI framework.

    class MyWindow(Window):
        contents = (
            para('Hello World!'),
            button('Click Me', id='ok'),
            para('Epilog'),
        )
    
        def __init__(self):
            self['#ok'].click(self.message)
            self['para'].hover(self.blend_in, self.blend_out)
    
        def message(self):
            print 'You clicked!'
    
        def blend_in(self, object):
            object.background = '#333333'
    
        def blend_out(self, object):
            object.background = 'WindowBackground'
    
    0 讨论(0)
提交回复
热议问题