views:

81

answers:

1

I am trying to write a simple custom button in wx.Python. My code is as follows, an error is thrown on line 19 of my "Custom_Button.py" - What is going on? I can find no help online for this error and have a suspicion that it has to do with the Polymorphism. (As a side note: I am relatively new to python having come from C++ and C# any help on syntax and function of the code would be great! - knowing that, it could be a simple error. thanks!)

Error

def __init__(self, parent, id=-1, NORM_BMP, PUSH_BMP, MOUSE_OVER_BMP, **kwargs):
      SyntaxError: non-default argument follows default argument

Main.py

class MyFrame(wx.Frame):
    def __init__(self, parent, ID, title):
        wxFrame.__init__(self, parent, ID, title,
                         wxDefaultPosition, wxSize(400, 400))

        self.CreateStatusBar()
        self.SetStatusText("Program testing custom button overlays")
        menu = wxMenu()
        menu.Append(ID_ABOUT, "&About", "More information about this program")
        menu.AppendSeparator()
        menu.Append(ID_EXIT, "E&xit", "Terminate the program")
        menuBar = wxMenuBar()
        menuBar.Append(menu, "&File");
        self.SetMenuBar(menuBar)

        self.Button1 = Custom_Button(self, parent, -1, 
                                "D:/Documents/Python/Normal.bmp", 
                                "D:/Documents/Python/Clicked.bmp",
                                "D:/Documents/Python/Over.bmp",
                                "None", wx.Point(200,200), wx.Size(300,100))

        EVT_MENU(self, ID_ABOUT, self.OnAbout)
        EVT_MENU(self, ID_EXIT,  self.TimeToQuit)

    def OnAbout(self, event):
        dlg = wxMessageDialog(self, "Testing the functions of custom "
                              "buttons using pyDev and wxPython",
                              "About", wxOK | wxICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()


    def TimeToQuit(self, event):
        self.Close(true)



class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(NULL, -1, "wxPython | Buttons")
        frame.Show(true)
        self.SetTopWindow(frame)
        return true

app = MyApp(0)
app.MainLoop()

Custom Button

import wx
from wxPython.wx import *

class Custom_Button(wx.PyControl):
                                    ############################################
                                  ##THE ERROR IS BEING THROWN SOME WHERE IN HERE ##
                                    ############################################
                                    # The BMP's
    Mouse_over_bmp = wx.Bitmap(0)   # When the mouse is over
    Norm_bmp = wx.Bitmap(0)         # The normal BMP
    Push_bmp = wx.Bitmap(0)         # The down BMP

    Pos_bmp = wx.Point(0,0)         # The posisition of the button

    def __init__(self, parent, NORM_BMP, PUSH_BMP, MOUSE_OVER_BMP, text="", 
                pos, size, id=-1, **kwargs):
        wx.PyControl.__init__(self,parent, id, **kwargs)

        # Set the BMP's to the ones given in the constructor
        self.Mouse_over_bmp = wx.Bitmap(MOUSE_OVER_BMP)
        self.Norm_bmp = wx.Bitmap(NORM_BMP)
        self.Push_bmp = wx.Bitmap(PUSH_BMP)
        self.Pos_bmp = pos

                                    ############################################
                                  ##THE ERROR IS BEING THROWN SOME WHERE IN HERE ##
                                    ############################################

        self.Bind(wx.EVT_LEFT_DOWN, self._onMouseDown)
        self.Bind(wx.EVT_LEFT_UP, self._onMouseUp)
        self.Bind(wx.EVT_LEAVE_WINDOW, self._onMouseLeave)
        self.Bind(wx.EVT_ENTER_WINDOW, self._onMouseEnter)
        self.Bind(wx.EVT_ERASE_BACKGROUND,self._onEraseBackground)
        self.Bind(wx.EVT_PAINT,self._onPaint)

        self._mouseIn = self._mouseDown = False

    def _onMouseEnter(self, event):
        self._mouseIn = True

    def _onMouseLeave(self, event):
        self._mouseIn = False

    def _onMouseDown(self, event):
        self._mouseDown = True

    def _onMouseUp(self, event):
        self._mouseDown = False
        self.sendButtonEvent()

    def sendButtonEvent(self):
        event = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
        event.SetInt(0)
        event.SetEventObject(self)
        self.GetEventHandler().ProcessEvent(event)

    def _onEraseBackground(self,event):
        # reduce flicker
        pass

    def _onPaint(self, event):
        dc = wx.BufferedPaintDC(self)
        dc.SetFont(self.GetFont())
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()
        dc.DrawBitmap(self.Norm_bmp)

        # draw whatever you want to draw
        # draw glossy bitmaps e.g. dc.DrawBitmap
        if self._mouseIn:   # If the Mouse is over the button
            dc.DrawBitmap(self, self.Mouse_over_bmp, self.Pos_bmp, useMask=False)
        if self._mouseDown: # If the Mouse clicks the button
            dc.DrawBitmap(self, self.Push_bmp, self.Pos_bmp, useMask=False)
+1  A: 

In function definitions, arguments with default values need to be listed after arguments without defaults, but before *args and **kwargs expansions

Before:

def __init__(self, parent, id=-1, NORM_BMP, PUSH_BMP, MOUSE_OVER_BMP, text="", 
                pos, size, **kwargs)

Corrected:

def __init__(self, parent, NORM_BMP, PUSH_BMP, MOUSE_OVER_BMP, 
                pos, size, id=-1, text="", **kwargs)
Jeremy Brown
is this a wxPython Syntax problem or is this a general rule of thumb? - I changed this... with the same result (see above?)...
Wallter
That's purely a Python syntax issue. That eliminates ambiguity for positional arguments when you call the function. Arguments with default values are implicitly specified if you do not specify it when calling the function.
Jeremy Brown
@Wallter - just saw the updated code - you also have an argument "text" with a default of "". You'll need to move it as well.
Jeremy Brown
Yeah that did it... Though when that was fixed it started throwing different errors?
Wallter
That sounds like you might have another question to post :-). Make sure to include the traceback!
Jeremy Brown