Hi,

i have a program where i use a while loop to create buttons dynamically.

Each button is created with, for a label, the name of one the drives on the machine(using the result of the fsutils command).

Up to this point everything works fine, if i have drive C: and drive D: available on my computer, then program is gonna create two wx.Buttons which will be displayed with the drive name as the label on each button.

Now, i want to be able to bind the dynamically created buttons to the listDir() method so that for example, when i try and click on one of the created buttons it executes a dir command using the drive letter just selected.

Only, the listDir() method is constantly referring to the last button that it has been bound to in the while loop... .
In other words, if i have two drives on my computer, C: and D:, the program will create two buttons, one with C: and the other one with D: on the label, and wether i click on either the C: or the D: button, i end up with the same result as if i had clicked twice on the D: button only...

Obviously, i understand that the listDir method will automatically refer to the last button that it has been bound to, even if you dynamically assigned a 'name' parameter to the button.

But there has got to be a way to bind 'unique' events to buttons created dynamically, hasn't there?

Thanks for your suggestions,
rc

Recommended Answers

All 4 Replies

Hmmm,
you might want to give us a code sample of what you have written.

(please wrap your code in code tags)

# your code here
# press Quote Reply to see the tags

-

Oh, sorry for not posting the code.
Here it is :

global tx,dv,dv2,dv3,dv_final,name    
        loc=8
        tx=1
        bt=1

        while tx<=nb_bt:
            dv=str(occ[tx])
            dv2=str(occ[tx])
            dv3='bt'+dv.strip(":")
            name=dv3
            dv3= wx.Button(self, tx, dv, wx.Point(loc,50),name=dv)
            self.Bind(wx.EVT_BUTTON,self.listDir, dv3)
            tx=tx+1
            loc=loc+80


def listDir(self,e):
        dv_final='dir '+dv3.GetName()
        ..........

Any ideas?

thxs

Hi python_dev,

I don't use wxPython to do GUI stuff, but I think I can see what the problem is, and how to fix it. You can't use dv3 inside listDir() to figure out which button was just pressed. Rather, you need to get that button's ID by going through 'e', the event object that is passed in as an argument to listDir(). I think the syntax is e.getId(). But I don't think this gives you a reference to the button itself - you'll have to create a dictionary of the form [button ID -> button widget], populate it in your while loop, and lookup the button widget in listDir(), then grab its name. Does that make sense?

Hi G-Do,

and thank you very much for your reply. Well, you were right and it works very well now!.
I had already had the idea of using a dictionary but the way i implemented it was without the use of e.GetId. And eveytime i had used the GetId() method, that was without using a dictionary :)

Well, here's the wining code, hoping it might help other developpers who're going thru such a situation...

global tx,dv,dv2,dv3,dv_final,lst,dfg,name
        lst={}          #creates dictionary       
        loc=8           # variable to set the X location of the buttons dynamically
        tx=1            #just another counter type like variable
        
        while tx<=nb_bt:
            dv=str(occ[tx])          #occ is the result of a regex.finall() apllied on a fsutils command
            dv3='bt'+dv.strip(":")                #here stripping the ':' caracter so it does not interfere with the creation of the buttons
            lst[tx]=dv                 #creates a dictionary of the form  1 --> C: 
            name=dv3                # dynamically assigns a name for each button but this is not mandatory
            
            #now onto creating the butons dynamically - note that the id is set to the value of tx
            dv3= wx.Button(self, tx, dv, wx.Point(loc,50),name=dv)
            
           # here we bind the freshly created buttons to the Defrag method(called Defrag but this isn't really what it does though....)
            self.Bind(wx.EVT_BUTTON,self.Defrag, dv3)
            
            #reincrementing tx as well as loc
            tx=tx+1       
            loc=loc+80

   
   def Defrag(self,e):
        selected_drive=lst[e.GetId()]       #here retrieving the drive letter inside the dictionary, and this according to the id of the event(e.GetId()) 
        ......

So, thanks again for your help,
python_dev

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.