Learning Poser Python...

Discussion in 'Scripts - Poser' started by Ken1171, Jun 9, 2018.

  1. Ken1171

    Ken1171 Dances with Bees Contributing Artist

    When the compiler cannot find a module's definition, it tells us it's not defined.

    I am using mostly from a import b, because it saves me work of having to type the module name every time. The compiler tells me the module I have tried to import is not defined. If I copy the modules back to the same folder, everything works. Adding the external path to sys.path is the part that doesn't seem to work here. I assume if the problem would be in the code, it wouldn't work no matter where I place the modules and classes. Example of how I am declaring it below:

    sys.path.append(externalModulePath)

    from a import b

    b.doSomething() <<== Error here, compiler claiming class "b" was not defined, which means module "a" was not found.


    The same happens with reload(). I once thought I got it working because the compiler would give me no errors on the line where a module is being reloaded, but errors I get from the imported class I have tried to reload still display the old code, and not the new one. That's how I know nothing was reloaded. Example of how I am declaring it below:

    from a import b

    reload(a)

    b.doSomething() <<== Error here, because module "a" is still using the old code (not reloaded).
     
  2. phdubrov

    phdubrov Noteworthy Contributing Artist

    This should not be this way. I.e. Python should throw an error on import statement if it can not find the path to a.
    Again:
    proper structure
    dir a - package
    __init__.py
    b.py - module
    class c: ...


    usage:
    either

    sys.path.append(path_to_a)
    from a import b
    reload(b)
    b.c.doSomething() (not c.doSomething())

    or

    sys.path.append(path_to_a)
    from a.b import c
    #You can't use reload here, as reload only accepts module as the argument. Partial import of a module now is considered a bad style.
    c.doSomething()
     
  3. Ken1171

    Ken1171 Dances with Bees Contributing Artist

    I have suspected there was something I wasn't understanding about Python when it comes to it's files organization. For example, in Adobe ActionScript 3.0, we have a notion of "package", and "Classes". All classes must be declared inside a package, and a package defines a "namespace", which is how we identify where the classes are stored at. In AS3, a package can only contain 1 single class.

    In Python, I could only identify what it calls a "module", which is just the .py file that contains the classes. The documentation claims the import statements can reference a module, but I didn't know Python also has "packages". The meaning of things differ from one language to another, so I am not sure what packages mean in Python. Is that a namespace like in AS3? How do we declare a package?

    I am coming from AS3, so the modules (.py files) I create contain only 1 class, even though I know Python allows creating as many classes in module. I am used to the idea that 1 file = 1 class, because that allows me to easily migrate a UML diagram into a working program, where each block is a class.

    This is why I am confused with the structure you have showed me.

    sys.path.append(path_to_a)
    from a import b
    reload(b)
    b.c.doSomething()


    If "a" is a module (.py file), and "b" is a class from the module, then what is "c"? Maybe this is the part I am not understanding from the Python structure organization.
     
  4. phdubrov

    phdubrov Noteworthy Contributing Artist

    Module - a .py file.
    Package - a folder with __init__.py file.
    Both can be imported via import statement. Both have type module on import. So many people (I too) sometimes use names not strictly. (Also there is a possibility to import from a zip, to create a module dynamically... but this not matter here).

    if a - a module, and b - a class in it, the only way to use reload is:
    Code:
    import a
    reload(a)
    i = a.b()
    i.something() 
    If you use from a import b, reload(a) will not work, 'cause name a is not defined.

    Can't say anything about problems with sys.path without real code examples.
     
    Ken1171 likes this.
  5. Ken1171

    Ken1171 Dances with Bees Contributing Artist

    Thanks for clarifying this! Now I have a better chance of figuring things out. ^^

    I was making a GUI with tkinter, where the user has to make selections from 2 listboxes, but whenever the other one is clicked, the visual selections from the first listbox disappear. The items are still selected, but we cannot see then anymore. Is this normal?
     
  6. phdubrov

    phdubrov Noteworthy Contributing Artist

    Never worked with Tkinter, so IDK
     
  7. Ken1171

    Ken1171 Dances with Bees Contributing Artist

    That's alright, I will figure it out. Thanks! ^^
     
  8. Ken1171

    Ken1171 Dances with Bees Contributing Artist

    Just now I have created my first Poser tool using Tkinter, and it was interesting the way the layout works with it. It's very similar to Adobe Flex, in the sense that it uses HTML-like layouts. Now I have started to look into wxPython, and it's a whole world of difference in looks and functionality. wxPython has widgets more similar to modern Windows interfaces, and is what Poser 11 uses under the hood. The widgets declarations still look alike the Adobe Flex framework, but I like the visuals better.

    I will start experimenting with wxPython GUI building, and try to integrate it with Poser. I am doing this in parallel with the upcoming Drako outfit, Body Type-4 and an a collab product with VolpeBox. So much to do, so little time. I need longer days, and why do we have to sleep so much? :)
     
  9. Ken1171

    Ken1171 Dances with Bees Contributing Artist

    I have managed to create my first wxPython interface, and it looks much better than Tkinter. It also offers more options to configure the interface.

    However, I am stuck when it comes to communication between modules. My interface generates events, but apparently only its own module can listen to them. I have 2 modules: a launcher and the GUI (which implements a wxPython app). The launcher creates a GUI class, and needs to listen to the events it generates. So far I could only listen to events inside it's own module. How can I make the launcher module listen to the events triggered by the GUI module?
     
  10. Ken1171

    Ken1171 Dances with Bees Contributing Artist

    Ok, I have done some research, and now I am answering my own question. I needed to use events to communicate actions between 2 modules, and looks like Python doesn't have any event-driven capabilities built-in into the language. Classes in different modules can only communicate by direct call - there are no events between classes like in other languages. It looks like if we want to program with events, we have to implement the event system ourselves, which is quite unusual when it comes to programming languages.

    This explains why so many web pages I have found covering "Class events" in Python were so misleading - each was implementing their own system to allow classes from different modules to dispatch and listen to events. Every other language I have used so far had event-driven classes built-in, so I guess I was taking those for granted all this time, because Python classes don't support any of that unless we implement it ourselves.

    Not surprisingly, there are 3rd party packages that implement class events, since this is such an essential functionality. I was just surprised that Python didn't have this built-in like in other languages. Quite a shocking discovery to me.
     

Share This Page