[Python] Function pointers & array of objects

  • Python
  • Thread starter cpscdave
  • Start date
  • #1
402
120
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:

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?
 

Answers and Replies

  • #2
34,027
5,681
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:

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?
This is what I would try. Just above where you are setting objects, do this:
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.
 
  • #3
90
19
Replace dictionary with instance of class object, call member function?
 
  • #4
402
120
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.
 
  • #5
90
19
Code:
class Control:
    pass

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:
  • Like
Likes cpscdave
  • #6
402
120
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:
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:

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
 
  • #7
402
120
Excellent it did indeed work!
Thanks Carno Raar & Mark44!
 

Related Threads on [Python] Function pointers & array of objects

  • Last Post
Replies
0
Views
2K
  • Last Post
Replies
2
Views
3K
  • Last Post
Replies
5
Views
2K
  • Last Post
Replies
3
Views
3K
  • Last Post
Replies
10
Views
3K
  • Last Post
Replies
3
Views
1K
  • Last Post
Replies
16
Views
3K
Replies
2
Views
10K
Replies
6
Views
6K
Top