Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Python [Python] Function pointers & array of objects

  1. Apr 29, 2015 #1
    Maybe I am going about this the wrong way.
    I'm trying to build a form to display & update information in a object.
    The objects are stored in an array since I'll have 1-N of them.

    What I've done now is created an array of dictonaries which hold the information about the form fields, it contains information such as: Label, control Type, and then a pointer to the get & set functions of the object field.

    This works great if I define the array AFTER I know which index the object is in.
    Is there a way I can do this before? Otherwise I'll have to have a similar array elsewhere to handle the actual updating of the object.

    Code is as follows:

    Code (Python):

                    objects = [{'name': 'theName',        'type' : 'textBox',  'lbl': 'Controller Name:','getFunction' :  theControllers[index].getName,        'setFunction' :  theControllers[index].setName},
                               {'name': 'theModbusID',    'type' : 'textBox',  'lbl': 'Modbus ID:',      'getFunction' :  theControllers[index].getModbus,      'setFunction' :  theControllers[index].setModbus},
                               {'name': 'theLocation',    'type' : 'textBox',  'lbl': 'Location:',       'getFunction' :  theControllers[index].getLocation,    'setFunction' :  theControllers[index].setLocation},
                               {'name': 'theChannel',     'type' : 'textBox',  'lbl': 'Com Channel',     'getFunction' :  theControllers[index].getComChannel,  'setFunction' :  theControllers[index].setComChannel},
                               {'name': 'theFirstCircuit','type' : 'textBox',  'lbl': 'First Circuit:',  'getFunction' :  theControllers[index].getFirstCiruit, 'setFunction' :  theControllers[index].setFirstCircuit},
                               {'name': 'theControlType', 'type' : 'dropDown', 'lbl': 'Controller Type:','getFunction' :  theControllers[index].getFirstCiruit, 'setFunction' :  theControllers[index].setFirstCircuit}]
                    for i in range(0, len(objects)):
                           #set up the controlls
    basically I want to be able to remove theControllers[index] from the function pointer. Is this possible?
  2. jcsd
  3. Apr 29, 2015 #2


    Staff: Mentor

    This is what I would try. Just above where you are setting objects, do this:
    Code (Python):
    fnPtr = theControllers[index]
    Then, wherever you have "theControllers[index].whatever", replace theControllers[index] with fnPtr.
    I don't see why this wouldn't work, but I haven't tested it.
  4. Apr 30, 2015 #3
    Replace dictionary with instance of class object, call member function?
  5. May 1, 2015 #4
    The goal is to not have to write a bunch of code to build the form.
    With my dictonary of info I only need to have a couple lines of code for each type of control (right now its only a text box and a dropdown)

    As per Mark44's suggestion, its the .whatever that is the important part. I'm not sure how I can implement it the way you suggest while still accomplishing what I want to do.

    The code will launch however if I replace the theController[index].whatver with controller.whatever. controller being the name of the class.
    However when it tries to run the code it says it needs an instance of the object.

    This would work if I could in the code tell it which controller to use.
  6. May 1, 2015 #5
    Code (Text):

    class Control:

    class Button (Control):
        def redraw(self):
            # draw a buttom
        def on_click(self):
            # whatever
        def __init__ (self, *, name='', icon=''... )
            # create

    class ListBox (Control):
        def redraw(self):
            # draw a list box
        def on_click(self):
            # whatever
        def __init__ (self, *, name='', entries=''... )
            # create

    objects = [
        Button(name='next_btn', icon='/icons/next.png', ...),
        ListBox(name='animal_sel', entries=['cat', 'rabbit', 'horse'], ...),
        Button(name='ok_btn', icon='/icons/ok.png', ...)
    #you could do that as a dict, with the control name ('animal-sel')
    #as the key, should you need to find your buttons quickly. But you
    #shouldn't really need to do this unless they can change at runtime,
    #like the contents of a list box

    for i in objects:
        i.redraw ()
    Otherwise I don't understand what you're trying to do.

    Window manager design patterns are pretty standard in OOP, may want to look at TKINTER in the python standard library to see how they do it.

    edit: Or you know, just use TKinter and not reinvent the wheel :)

    edit: Why this site doesn't implement a line length count for entering code? (And why people don't line break their own code at like, 80 or 120, or somewhere that can be read without scrolling?)
    Last edited: May 1, 2015
  7. May 1, 2015 #6
    Carno Raar:
    Lol this is my problem. I'm not sure how to explain (well) what I'm trying to do exactly.
    I think you're on the right track. What you posted (I think) is pretty much exactly what I am trying to do.
    As a side note, I'm trying to conform to another development team in another office, in another country lol. They were using WXpython for their GUI but have since switch to QT. I'll spend this morning switching to QT myself and see if a solution comes out of the change.

    In your code you had:
    Code (Python):
    objects = [
        Button(name='next_btn', icon='/icons/next.png', ...),
        ListBox(name='animal_sel', entries=['cat', 'rabbit', 'horse'], ...),
        Button(name='ok_btn', icon='/icons/ok.png', ...)
    which is essentially my Objects dictionary. What I would like to do, is to define this dictionary (or whatever other construct) in 1 spot. (Actually just may have had a flash of brilliance. I'll post my idea after I finish this thought).
    The problem I have, is where you have name = 'next_btn' for example I want to pull 'next_btn' from an object via a getter function. (eg theObjects[index].getName)
    The issue is when I define the dictionary I need to know the index of the object that I'm working on.

    My (probably painfully obvious and straight forward) solution that I think should work is:
    I'm going to create a function inside the object called "getFormData"
    it will then be something like:

    Code (Python):

    def getFormData(self):              
         objects = [{'name': 'theName',        'type' : 'textBox',  'lbl': 'Controller Name:','getFunction' :  self.getName,        'setFunction' :  self.setName} .... ]
         return objects
    This solves the problem of getting the object instances functions AND having the data only defined in one spot!

    I'll post shortly if this does indeed work
  8. May 1, 2015 #7
    Excellent it did indeed work!
    Thanks Carno Raar & Mark44!
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook