In wxpython, is it possible to populate something inside of a gui element that is defined by an xrc file

Question:

I have a wxpython gui, which I defined in an xrc file, the root item (idk if that is the right term) of this gui is a wxFrame, which I load into a wxDialog window. I want to then populate stuff, inside of this gui, from python, but I can’t seem to be able to do this.

As an example, lets say I have the following 2 files:

test.py:

import wx
import wx.xrc

class GUI(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(400,800), style = wx.TAB_TRAVERSAL)

        # Create an instance of the XmlResource class and load the resource file
        xml_resource = wx.xrc.XmlResource()
        xml_resource.Load('test.xrc')

        # Create a box sizer for the dialog
        outer_sizer = wx.BoxSizer(wx.VERTICAL)
        
        # Load the panel object from the resource file and add it to the outer sizer
        panel = xml_resource.LoadObject(self, 'panel', 'wxPanel')
        outer_sizer.Add(panel, 1, wx.EXPAND)

        panel2 = xml_resource.LoadObject(self, 'panel2', 'wxPanel')

        # Set the dialog's sizer
        self.SetSizer(outer_sizer)

# Create a wx.App instance and run the main dialog
app = wx.App()
dialog = GUI(None)
dialog.Show()
app.MainLoop()

test.xrc:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<resource xmlns="http://www.wxwidgets.org/wxxrc" version="2.5.3.0">
    <object class="wxPanel" name="panel">
        <style>wxTAB_TRAVERSAL</style>
        <object class="wxBoxSizer">
            <orient>wxVERTICAL</orient>
            <object class="sizeritem">
                <option>1</option>
                <flag>wxEXPAND | wxALL</flag>
                <border>5</border>
                <object class="wxPanel" name="panel2">
                    <style>wxTAB_TRAVERSAL</style>
                    <bg>#4b6983</bg>
                </object>
            </object>
        </object>
    </object>
</resource>

Then panel will load correctly, but it will throw an error: (XRC error: XRC resource "panel2" (class "wxPanel") not found. So my question would be: how would one properly load a panel (or a scrollbox, or a sizer, etc) that has been defined in an xrc file into python, so that it can be populated? And is that even possible?

Asked By: TT-392

||

Answers:

Let’s run with a second attempt, now you have defined a little more, of what you’re trying to achieve.

the wx.xrc module allows you to request the name and/or id of an object within the xrc resource. So in your case, this could result in:

import wx
import wx.xrc

class GUI(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(400,800), style = wx.TAB_TRAVERSAL)

        # Create an instance of the XmlResource class and load the resource file
        xml_resource = wx.xrc.XmlResource()
        xml_resource.Load('test.xrc')

        # Create a box sizer for the dialog
        outer_sizer = wx.BoxSizer(wx.VERTICAL)

        # Load the panel object from the resource file and add it to the outer sizer
        panel = xml_resource.LoadObject(self, 'panel', 'wxPanel')
        outer_sizer.Add(panel, 1, wx.EXPAND)

        self.panel2 = wx.xrc.XRCCTRL(self, "panel2")

        self.cb = wx.ComboBox(self.panel2, wx.ID_ANY, choices=[("Choice 1"), ("Choice 2")], style=wx.CB_READONLY)

        # Set the dialog's sizer
        self.SetSizer(outer_sizer)

# Create a wx.App instance and run the main dialog
app = wx.App()
dialog = GUI(None)
dialog.Show()
app.MainLoop()

Here the resource object defined in the xrc file as panel2 is defined within the code and then is available to be accessed as such.

For the record, for the id use wx.xrc.XRCID("panel2")

In your example, this results as follows, if I add in a wx.ComboBox

enter image description here

Answered By: Rolf of Saxony
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.