Align things to the right in a horizontal BoxSizer in XRC?

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
pythonmegapixel
In need of some credit
In need of some credit
Posts: 3
Joined: Wed Apr 28, 2021 3:52 pm

Align things to the right in a horizontal BoxSizer in XRC?

Post by pythonmegapixel » Wed Apr 28, 2021 4:08 pm

I have a horizontal wxBoxSizer inside a vertical wxBoxSizer which will contain three buttons.
By default the buttons are laid out like this:
Image

but I want them laid out like this (this is an edited image)
Image

Here is the C++ I am using:

Code: Select all

#include <wx/wxprec.h>

#ifndef WX_PRECOMP
    #include <wx/wx.h>
#endif

#include <wx/xrc/xmlres.h>


class MyApp : public wxApp {
public:
    virtual bool OnInit();
};

wxIMPLEMENT_APP(MyApp);

bool MyApp::OnInit() {
    wxXmlResource::Get()->InitAllHandlers();
    wxXmlResource::Get()->Load("res.xrc");

    wxFrame* MainFrame = wxXmlResource::Get()->LoadFrame(NULL, "MainFrame");
    if ( !MainFrame ) {
        wxLogError("A file (res.xrc) required to run is missing!");
        return false;
    }

    MainFrame->Show();


    return true;
}
and here is the XRC, from the file res.xrc, defining the relevant section:

Code: Select all

<?xml version="1.0" ?>
<resource>
    <object class="wxFrame" name="MainFrame">
            <object class="wxBoxSizer" name="TopLevelSizer">
                <orient>wxVERTICAL</orient>
              
              <!-- Various sizeritems for other controls go here -->
              
            <object class="sizeritem">
                <object class="wxBoxSizer">
                    <orient>wxHORIZONTAL</orient>

                            
                    <object class="sizeritem">
                        <object class="wxButton">
                            
                            <label>Should be on left</label>

                        </object>
                    </object>

                    <object class="sizeritem">
                        <object class="wxButton">                            
                            
                            <label>Should be on left</label>

                        </object>
                    </object>

                    <object class="sizeritem">
                        <object class="wxButton">
                            
                            <label>Should be on right</label>

                        </object>
                    </object>
             </object>
            </object>             
            </object>
        </object>
</resource>
How can I modify my code so that this works as intended?

User avatar
doublemax
Moderator
Moderator
Posts: 16014
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Align things to the right in a horizontal BoxSizer in XRC?

Post by doublemax » Wed Apr 28, 2021 5:09 pm

You need a stretchspacer between the 2nd and 3rd button. When using code it's wxSizer::AddStretchSpacer(int prop)
https://docs.wxwidgets.org/trunk/classw ... 747af5c976

When using a GUI editor, you'll probably find that somewhere, too :)
Use the source, Luke!

pythonmegapixel
In need of some credit
In need of some credit
Posts: 3
Joined: Wed Apr 28, 2021 3:52 pm

Re: Align things to the right in a horizontal BoxSizer in XRC?

Post by pythonmegapixel » Wed Apr 28, 2021 5:41 pm

doublemax wrote:
Wed Apr 28, 2021 5:09 pm
You need a stretchspacer between the 2nd and 3rd button. When using code it's wxSizer::AddStretchSpacer(int prop)
https://docs.wxwidgets.org/trunk/classw ... 747af5c976

When using a GUI editor, you'll probably find that somewhere, too :)
Hi there, thanks for your input.

As this is just a small little application, I wasn't bothering with a GUI editor and was just writing the XRC file myself.
I'm currently installing wxFormBuilder and I'm going to attempt to add a stretchspacer and see what it spits out which will hopefully answer my question!

User avatar
doublemax
Moderator
Moderator
Posts: 16014
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Align things to the right in a horizontal BoxSizer in XRC?

Post by doublemax » Wed Apr 28, 2021 5:48 pm

The documentation is not very clear, my guess is you have to use a "spacer" entry with just "option" = 1
https://docs.wxwidgets.org/3.1.5/overvi ... mat_sizers

Code: Select all

        <object class="spacer">
          <option>1</option>
        </object>
Use the source, Luke!

pythonmegapixel
In need of some credit
In need of some credit
Posts: 3
Joined: Wed Apr 28, 2021 3:52 pm

Re: Align things to the right in a horizontal BoxSizer in XRC?

Post by pythonmegapixel » Wed Apr 28, 2021 6:32 pm

I tried copying the output from wxFormBuilder, which didn't work. The documentation is, as you say, pretty useless on this, and playing around with different options on a spacer object didn't really help either.

I might just rebuild my entire UI using wxFormBuilder and see if I can get it to work that way. I've already designed it once so hopefully it shouldn't take me too long!

User avatar
doublemax
Moderator
Moderator
Posts: 16014
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Align things to the right in a horizontal BoxSizer in XRC?

Post by doublemax » Wed Apr 28, 2021 6:37 pm

I found that code snippet with the spacer here: https://wiki.wxpython.org/pywxrc
Maybe if you see it in context, you can spot why it fails. But i'm almost certain it works.
I might just rebuild my entire UI using wxFormBuilder and see if I can get it to work that way. I've already designed it once so hopefully it shouldn't take me too long!
Another option might be to build the gui with code. Especially if it's not very complex.
Use the source, Luke!

PB
Part Of The Furniture
Part Of The Furniture
Posts: 3041
Joined: Sun Jan 03, 2010 5:45 pm

Re: Align things to the right in a horizontal BoxSizer in XRC?

Post by PB » Wed Apr 28, 2021 7:22 pm

FWIW: I have no real experience but what doublemax posted works for me. Obviously, when that spacer has its proportion set to 1, it is expected that the buttons have it set to 0, so only the sizer expands fully, pushing the last button to the right.
xfc-frame.png
xfc-frame.png (2.13 KiB) Viewed 748 times

XRC generated by wxFormBuilder

Code: Select all

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<resource xmlns="http://www.wxwindows.org/wxxrc" version="2.3.0.1">
	<object class="wxFrame" name="MyFrame">
		<style>wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL</style>
		<title></title>
		<centered>1</centered>
		<aui_managed>0</aui_managed>
		<object class="wxBoxSizer">
			<orient>wxHORIZONTAL</orient>
			<object class="sizeritem">
				<option>0</option>
				<flag>wxALL</flag>
				<border>5</border>
				<object class="wxButton" name="m_button1">
					<label>MyButton</label>
					<default>0</default>
					<markup>0</markup>
					<bitmap />
				</object>
			</object>
			<object class="sizeritem">
				<option>0</option>
				<flag>wxALL</flag>
				<border>5</border>
				<object class="wxButton" name="m_button2">
					<label>MyButton</label>
					<default>0</default>
					<markup>0</markup>
					<bitmap />
				</object>
			</object>
			<object class="spacer">
				<option>1</option>
				<border>5</border>
				<size>0,0</size>
			</object>
			<object class="sizeritem">
				<option>0</option>
				<flag>wxALL</flag>
				<border>5</border>
				<object class="wxButton" name="m_button3">
					<label>MyButton</label>
					<default>0</default>
					<markup>0</markup>
					<bitmap />
				</object>
			</object>
		</object>
	</object>
</resource>
C++ code loading the frame

Code: Select all

#include <wx/wx.h>
#include <wx/xrc/xmlres.h>

class MyApp : public wxApp
{
public:
    bool OnInit() override
    {
        wxXmlResource::Get()->InitAllHandlers();
        wxXmlResource::Get()->Load("minimal.xrc");

        wxFrame* frame = wxXmlResource::Get()->LoadFrame(nullptr, "MyFrame");

        if ( !frame )
            return false;

        frame->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);
The only odd thing is that the frame is shown fitted to its contents.

Post Reply