Search code examples
pythonfunctionuser-interfacewxpython

Shortening GUI code by passing parameters to definitions


I have been working on a GUI code in wxpython that more or less repeats the same information 4 times. There are a lot of buttons on the screen that I have had to bind events to, and I'm finding that I have a lot of on_button_click definitions that look almost identical. So, I was wondering if there was a way to just pass through a parameter when binding the button to an event and cutting out 3 of the definitions. Here is an example:

self.VDBenchSlot1 = wx.Button(self, -1, "Slot 1 VDBench")
sizer.Add(self.VDBenchSlot1,(1, 5), (1, 5), wx.EXPAND)
self.VDBenchSlot1.Bind(wx.EVT_BUTTON, self.VDBenchSlot1_clicked)

self.VDBenchSlot2 = wx.Button(self, -1, "Slot 2 VDBench")
sizer.Add(self.VDBenchSlot2,(1, 5), (1, 5), wx.EXPAND)
self.VDBenchSlot2.Bind(wx.EVT_BUTTON, self.VDBenchSlot2_clicked)

self.VDBenchSlot3 = wx.Button(self, -1, "Slot 3 VDBench")
sizer.Add(self.VDBenchSlot3,(1, 5), (1, 5), wx.EXPAND)
self.VDBenchSlot3.Bind(wx.EVT_BUTTON, self.VDBenchSlot3_clicked)

self.VDBenchSlot4 = wx.Button(self, -1, "Slot 4 VDBench")
sizer.Add(self.VDBenchSlot4,(1, 5), (1, 5), wx.EXPAND)
self.VDBenchSlot4.Bind(wx.EVT_BUTTON, self.VDBenchSlot4_clicked)

def VDBenchSlot1_clicked(self, event):       
    global diskchange
    if diskchange[1] == 'No Disk':
        self.TextSlot1.AppendText("No Disk is currently in the slot so you cannot run this! \n")
    else:  
        # Open the file startDisk#VD.sh that has the setup to start running VDBench
        os.system("echo pcieRocks | sudo -S gnome-terminal --profile=VDbench --working-directory=/home/pciedev3ubuntu/Documents -e './vdbench -f disk%dVDscript.txt -vr' &" %diskchange[1])

def VDBenchSlot2_clicked(self, event):
    global diskchange

    if diskchange[2] == 'No Disk':
        self.TextSlot2.AppendText("No Disk is currently in the slot so you cannot run this! \n")
    else:   
        # Open the file startDisk#VD.sh that has the setup to start running VDBench
        os.system("echo pcieRocks | sudo -S gnome-terminal --profile=VDbench --working-directory=/home/pciedev3ubuntu/Documents -e './vdbench -f disk%dVDscript.txt -vr' &" %diskchange[2])

def VDBenchSlot3_clicked(self, event):
    global diskchange

    if diskchange[3] == 'No Disk':
        self.TextSlot3.AppendText("No Disk is currently in the slot so you cannot run this! \n") 
    else:   
        # Open the file startDisk#VD.sh that has the setup to start running VDBench
        os.system("echo pcieRocks | sudo -S gnome-terminal --profile=VDbench --working-directory=/home/pciedev3ubuntu/Documents -e './vdbench -f disk%dVDscript.txt -vr' &" %diskchange[3])

def VDBenchSlot4_clicked(self, event):
    global diskchange

    if diskchange[4] == 'No Disk':
        self.TextSlot4.AppendText("No Disk is currently in the slot so you cannot run this! \n")
    else:   
        # Open the file startDisk#VD.sh that has the setup to start running VDBench
        os.system("echo pcieRocks | sudo -S gnome-terminal --profile=VDbench --working-directory=/home/pciedev3ubuntu/Documents -e './vdbench -f disk%dVDscript.txt -vr' &" %diskchange[4])

I've tried changing VDBenchslotx_clicked to VDBenchslotx_clicked() and passing parameters to it, but one of two things happen; it tells me that the parameters entered do not match the parameters of the def, or it lets my program run but it automatically executes the def at program startup and not when the button is pressed, and the button then does not function properly.


Solution

  • Use a lambda expression to pass arguments to bound functions. For example:

    self.VDBenchSlot1.Bind(wx.EVT_BUTTON, lambda event: self.VDBenchSlot_clicked(event, 1))
    
    def VDBenchSlot_clicked(self, event, position):   
        if position == 1:
            text_slot = self.TextSlot1
        elif position == 2:
            text_slot = self.TextSlot2
        elif position == 3:
            text_slot = self.TextSlot3
        elif position == 4:
            text_slot = self.TextSlot4    
        global diskchange
        if diskchange[position] == 'No Disk':
            text_slot.AppendText("No Disk is currently in the slot so you cannot run this! \n")
        else:  
            # Open the file startDisk#VD.sh that has the setup to start running VDBench
            os.system("echo pcieRocks | sudo -S gnome-terminal --profile=VDbench --working-directory=/home/pciedev3ubuntu/Documents -e './vdbench -f disk%dVDscript.txt -vr' &" %diskchange[position])