Trever Wagenhals
Trever Wagenhals

Reputation: 395

wxpython open new window with button click, pass parameters to new window

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

Upvotes: 0

Views: 517

Answers (1)

Quinn
Quinn

Reputation: 4504

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()

Upvotes: 0

Related Questions