0

Good evening/morning,

I am currently making a GUI with a lot of buttons, and some (9) of the buttons open a new window. This window is identical in all 9 cases in setup, but what this window changes when the user continues is based on which of the buttons were clicked. So, I want to make one button handler that handles all 9 buttons and makes a new window, but pass parameters to the new window. So, here is my code:

# Handles the creation of all of the buttons
def make_button(text, callback, starty, startx, height, width):
    button = wx.Button(self, -1, text)
    sizer.Add(button, (starty, startx), (height, width), wx.EXPAND)
    button.Bind(wx.EVT_BUTTON, callback)
    return button

make_button("Configure", lambda event: self.RailConfig_clicked(event, 1, 1), 10, 1, 1 ,1)
make_button("Configure", lambda event: self.RailConfig_clicked(event, 1, 2), 10, 2, 1 ,1)
make_button("Configure", lambda event: self.RailConfig_clicked(event, 1, 3), 10, 3, 1 ,1)

make_button("Configure", lambda event: self.RailConfig_clicked(event, 2, 1), 10, 6, 1 ,1)
make_button("Configure", lambda event: self.RailConfig_clicked(event, 2, 2), 10, 7, 1 ,1)
make_button("Configure", lambda event: self.RailConfig_clicked(event, 2, 3), 10, 8, 1 ,1)

make_button("Configure", lambda event: self.RailConfig_clicked(event, 3, 1), 10, 11, 1 ,1)
make_button("Configure", lambda event: self.RailConfig_clicked(event, 3, 2), 10, 12, 1 ,1)
make_button("Configure", lambda event: self.RailConfig_clicked(event, 3, 3), 10, 13, 1 ,1)

make_button("Configure", lambda event: self.RailConfig_clicked(event, 4, 1), 10, 16, 1 ,1)
make_button("Configure", lambda event: self.RailConfig_clicked(event, 4, 2), 10, 17, 1 ,1)
make_button("Configure", lambda event: self.RailConfig_clicked(event, 4, 3), 10, 18, 1 ,1)

def RailConfig_clicked(self, event, slot, rail):
    self.Rail1ConfigSlot1_window = NewWindow(parent=None, id= -1)
    self.Rail1ConfigSlot1_window.Show()
    print slot
    print rail

class NewWindow(wx.Frame):
    def __init__(self,parent,id):
        wx.Frame.__init__(self, parent, id, 'New Window')
        wx.Frame.CenterOnScreen(self)
        self.initialize()

    def initialize(self):
        sizer = wx.GridBagSizer()

        self.VoltageLabel = wx.StaticText(self, -1, 'Margin High Voltage', wx.DefaultPosition, wx.DefaultSize)
        sizer.Add(self.VoltageLabel, (0,0), (1,1))

        self.VoltageLabel2 = wx.StaticText(self, -1, 'Margin Low Voltage', wx.DefaultPosition, wx.DefaultSize)
        sizer.Add(self.VoltageLabel2, (3,0), (1,1))

        self.VoltageLabel3 = wx.StaticText(self, -1, 'Current Voltage Low Value', wx.DefaultPosition, wx.DefaultSize)
        sizer.Add(self.VoltageLabel3, (0,2), (1,1))

        self.VoltageLabel4 = wx.StaticText(self, -1, 'Current Voltage High Value', wx.DefaultPosition, wx.DefaultSize)
        sizer.Add(self.VoltageLabel4, (3,2), (1,1))

        self.SetSizerAndFit(sizer)
        self.SetSizeHints(-1,-1)
        self.SetAutoLayout(True)
        self.Show(True)
        for col in range(0,5):
                sizer.AddGrowableCol(col)

        self.editlow = wx.TextCtrl(self, -1, "", wx.DefaultPosition, wx.DefaultSize)
        sizer.Add(self.editlow, (1,0), (1,1), wx.EXPAND)

        self.submitlow = wx.Button(self, label="Submit")
        sizer.Add(self.submitlow, (5, 5), (1, 1), wx.EXPAND)

So, you can see that I pass two parameters to the RailConfig_clicked def, slot and rail, by using the lambda event call. Inside RailConfig_clicked, I create a new window, but I want to once again pass these variables to that new window so that I can use the information to decide what to change later.

I've tried putting the parameters into NewWindow like so:

self.Rail1ConfigSlot1_window = NewWindow(parent=None, id= -1, slot, rail)

but i get:

SyntaxError: non-keyword arg after keyword arg
1
  • Can you please post your whole source code? In self.Rail1ConfigSlot1_window = NewWindow(parent=None, id= -1, slot, rail), you passed four parameters, but the NewWindow class only requires two parameters (parent and id), so you got the SyntaxEror. Commented Apr 11, 2016 at 19:01

1 Answer 1

0

I'd like to suggest a different approach to create buttons and handle button-click events. Hope it helps:

# -*- coding: utf-8 -*- 

###########################################################################
import wx
import math
###########################################################################
## Class MyFrame1
## Different button triggers different message
###########################################################################

class MyFrame1 ( wx.Frame ):

    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = "Button group demo", pos = wx.DefaultPosition, size = wx.Size( 300,200 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )

        self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
        gSizer1 = wx.GridSizer( 3, 3, 0, 0 )
        # Loop to add (9) buttons
        Btn = lambda x: wx.Button( self.m_panel1, wx.ID_ANY, u"Configure", wx.DefaultPosition, wx.DefaultSize, 0, name = u"row:%d col:%d" % (math.ceil((x -1)/3) + 1, (x - 1)%3 + 1) )
        for i in range(1, 10):
            btn = Btn(i)
            gSizer1.Add( btn, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
            btn.Bind( wx.EVT_BUTTON, self.OnButtonClicked )         

        self.m_panel1.SetSizer( gSizer1 )
        self.m_panel1.Layout()
        gSizer1.Fit( self)  
        self.Centre( wx.BOTH )
        self.Show() 

    # Button click event handler
    def OnButtonClicked( self, event ):
        name = event.GetEventObject().GetName()
        # Here you can make a new window, and pass in parameters
        wx.MessageBox('In %s' % (name), 'Button Clicked')
        event.Skip()

if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame1(None)
    app.MainLoop()
Sign up to request clarification or add additional context in comments.

1 Comment

Funny, I posted another question asking why my for loop for creating multiple buttons wasn't working. Although it's not the answer to this question, I will try this to see if I can get that portion working. I'll update you tomorrow, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.