Search code examples
dialogwxpythonxrc

Using XRC to create custom Dialog boxes


I have been having trouble defining my own Dialogs which are described using XRC.

I have read http://nebelhom.blogspot.co.nz/2012/04/xrc-and-wxdialogs.html and other similar sources which tells me to do this:

class ConfigDialog(wx.Dialog):
    def __init__(self, parent):
            self.res = xrc.XmlResource("config_dialog.xrc")
            pre = wx.PreDialog()
            self.res.LoadOnDialog(pre, parent, "ConfigDlg")
            self.PostCreate(pre)

            #Bind controls to events

However, I am still very confused as to how you actually bind the controls to different methods defined in ConfigDialog class.

I tried

self.btn_1 = xrc.XRCCTRL(self.frame, 'btn_1')

and self.btn_1 = xrc.XRCCTRL(self, 'btn_1')

(because i read here that)

The PostCreate method is used to transfer the guts of pre into self, so it acts like it was a real instance of ConfigDialog.

but neither of them worked.

Would you be able to point me in the right direction?


Solution

  • I solved the problem using 2 step creation as documented here.

    Here's a small example

    # Import both wx main module and the xrc module
    import wx
    import wx.xrc as xrc
    
    class MyDialog(wx.Dialog):
        """
        This is our dialog. XRC will create it's widgets and all we need to do is
        handle the events.
        """
        def __init__(self, parent, res):
    
            pre = wx.PreDialog()
            self.PostCreate(pre)
    
            res.LoadOnDialog(self, None, "MyDialog")
    
            #Binding events
    
            self.Bind(wx.EVT_BUTTON, self.on_ok, xrc.XRCCTRL(self, "okButton"))
            self.Bind(wx.EVT_BUTTON, self.on_cancel, xrc.XRCCTRL(self, "cancelButton"))
    
        def on_ok(self, event):
            """Show a message box informing us we pressed the OK button"""
            msgDlg = wx.MessageDialog(self, "OK pressed", style=wx.OK)
            msgDlg.ShowModal()
            msgDlg.Destroy()
            self.Destroy()
    
        def on_cancel(self, event):
            """Show a message box informing us we pressed the Cancel button"""
            msgDlg = wx.MessageDialog(self, "Cancel pressed", style=wx.OK)
            msgDlg.ShowModal()
            msgDlg.Destroy()
            self.Destroy()
    
    
    # Create the simplest wxApp object
    app = wx.PySimpleApp()
    
    # Load the XRC resources
    res = xrc.XmlResource("example.xrc")
    
    # Show and run the dialog
    dlg = MyDialog(None, res)
    dlg.ShowModal() 
    

    and the XRC file:

    <?xml version="1.0" encoding="cp1255"?>
    <resource>
      <object class="wxDialog" name="MyDialog">
        <title></title>
        <object class="wxBoxSizer">
          <orient>wxVERTICAL</orient>
          <object class="sizeritem">
            <object class="wxStaticText">
              <label>Just a little bit of text to make
    the dialog a little bit less empty
    than it has to be for a simple
    example.</label>
              <font>
                <size>12</size>
                <family>default</family>
                <style>normal</style>
                <weight>normal</weight>
                <underlined>0</underlined>
              </font>
            </object>
            <flag>wxALL</flag>
            <border>5</border>
          </object>
          <object class="spacer">
            <size>0,20</size>
          </object>
          <object class="sizeritem">
            <object class="wxBoxSizer">
              <orient>wxHORIZONTAL</orient>
              <object class="spacer">
                <option>1</option>
              </object>
              <object class="sizeritem">
                <object class="wxButton" name="okButton">
                  <label>OK</label>
                </object>
                <flag>wxALL</flag>
                <border>5</border>
              </object>
              <object class="sizeritem">
                <object class="wxButton" name="cancelButton">
                  <label>Cancel</label>
                </object>
                <flag>wxALL</flag>
                <border>5</border>
              </object>
            </object>
            <flag>wxEXPAND</flag>
          </object>
        </object>
      </object>
    </resource> 
    

    finally, a small tip: To end the dialog, use EndModal(id) as such

    self.EndModal(wx.ID_OK)