splitter window

281 views
Skip to first unread message

David Bergman

unread,
Apr 20, 2018, 5:25:38 PM4/20/18
to wx-u...@googlegroups.com

I have been using wxWidgets for GUI dev for a few months now.  The samples are fairly easy to lean from but I'm trying to get something to work and need assistance.

I'm trying to make a graphic layout using multiple nested splitter windows.  What I've done seems to work in that it does produce the desired initial result.  However the sashes (or the panels/frames they outline) do not seem to resize properly.

A cut and paste snippet from the edited splitter window example is provided below.  After that are screen shots of the result in the initial state and after moving the sashes.  Since the original implementation resized I figured adding more would work the same, clearly not.

I have seen many similar posts on stack overflow and other blogs but only on how to make nested splitters by referring to the example, none that address this.  Thanks in advance for your help.


class MyFrame: public wxFrame
{
public:
    MyFrame();
    virtual ~MyFrame();
//  stuff from definition
private:
    wxWindow *m_left, *m_right;

    //  Added for testing nested splitters.
    wxWindow *m_up, *m_down;

    wxSplitterWindow* m_splitter;

    //  Added for testing nested splitters.
    wxSplitterWindow* m_splitter_2;

    wxWindow *m_replacewindow;

    wxDECLARE_EVENT_TABLE();
    wxDECLARE_NO_COPY_CLASS(MyFrame);
};

// My frame constructor
MyFrame::MyFrame()

//****************
//
//    Here is the beginning of the splitter stuff
//
//****************

    m_splitter = new MySplitterWindow(this);

//    wxPanel *panel = new wxPanel(this, wxID_ANY);
   
    wxBoxSizer *box1 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer *box2 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer *box3 = new wxBoxSizer(wxVERTICAL);

    // If you use non-zero gravity you must initialize the splitter with its
    // correct initial size, otherwise it will change the sash position by a
    // huge amount when it's resized from its initial default size to its real
    // size when the frame lays it out. This wouldn't be necessary if default
    // zero gravity were used (although it would do no harm neither).
    m_splitter->SetSize(GetClientSize());
    m_splitter->SetSashGravity(1.0);

   
//#if 1
    m_left = new MyCanvas(m_splitter, true);
    m_left->SetBackgroundColour(*wxRED);
    m_left->SetCursor(wxCursor(wxCURSOR_MAGNIFIER));

    //  Here is new code to add m_left to the boxSizer.
    box1->Add(m_left, 0);
    m_splitter->SetSizer(box1);

    m_right = new wxPanel(m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, NULL);
    m_right->SetFocus();

//#else // for testing kbd navigation inside the splitter
//    m_left = new wxTextCtrl(m_splitter, wxID_ANY, wxT("first text"));
//    m_right = new wxTextCtrl(m_splitter, wxID_ANY, wxT("second text"));
//#endif
   

    // you can also do this to start with a single window
//#if 0
//    m_right->Show(false);
//    m_splitter->Initialize(m_left);
//#else
    // you can also try -100
   m_splitter->SplitVertically(m_left, m_right, 100);
//#endif


//  Here is new nested splitter window functionality.
   m_splitter_2 = new wxSplitterWindow(m_right);
   m_splitter_2->SetSize(m_right->GetClientSize()); //GetClientSize());
   m_splitter_2->SetSashGravity(0.5);

   m_up = new MyCanvas(m_splitter_2, true);
   m_up->SetBackgroundColour(*wxGREEN);
   m_up->SetCursor(wxCursor(wxCURSOR_MAGNIFIER));
   m_up->SetFocus();

   //  Here is new code to add this to a boxSizer.
   box2->Add(m_up, 0);
   m_splitter_2->SetSizer(box2);

   m_down = new MyCanvas(m_splitter_2, false);
   m_down->SetBackgroundColour(*wxCYAN);
   m_down->SetFocus();

   //  Finally box3
   box3->Add(m_down, 0);
   m_splitter_2->SetSizer(box3);

   m_splitter_2->SplitHorizontally(m_up, m_down, 0);


#if wxUSE_STATUSBAR
    SetStatusText(wxT("Min pane size = 0"), 1);
#endif // wxUSE_STATUSBAR

    m_replacewindow = NULL;
}






Virus-free. www.avast.com

Igor Korot

unread,
Apr 20, 2018, 5:37:50 PM4/20/18
to wx-u...@googlegroups.com
Hi,

On Fri, Apr 20, 2018 at 4:22 PM, David Bergman <stuntgu...@gmail.com> wrote:

I have been using wxWidgets for GUI dev for a few months now.  The samples are fairly easy to lean from but I'm trying to get something to work and need assistance.

I'm trying to make a graphic layout using multiple nested splitter windows.  What I've done seems to work in that it does produce the desired initial result.  However the sashes (or the panels/frames they outline) do not seem to resize properly.

A cut and paste snippet from the edited splitter window example is provided below.  After that are screen shots of the result in the initial state and after moving the sashes.  Since the original implementation resized I figured adding more would work the same, clearly not.

I have seen many similar posts on stack overflow and other blogs but only on how to make nested splitters by referring to the example, none that address this.  Thanks in advance for your help.


What is the wx version?
Which OS/toolkit?
What compile? (doubt it depends on that, but jus in case)

Thank you.

David Bergman

unread,
Apr 20, 2018, 10:43:57 PM4/20/18
to wx-u...@googlegroups.com

Thanks for the reply.

What is the wx version?
3.1.0

Which OS/toolkit?
Windows 8.1/SDK 10.0.15063.0


What compile? (doubt it depends on that, but jus in case)
Visual Studio 2017, Visual C++ 14.1

Steve Barnes

unread,
Apr 21, 2018, 1:32:49 AM4/21/18
to wx-u...@googlegroups.com


On 21/04/2018 03:43, David Bergman wrote:
> Thanks for the reply.
>
> What is the wx version?
> 3.1.0
>
> Which OS/toolkit?
> Windows 8.1/SDK 10.0.15063.0
>
> What compile? (doubt it depends on that, but jus in case)
> Visual Studio 2017, Visual C++ 14.1
>
>

<SNIP>

David,

Can I strongly recommend prototyping in Python/wxPython & with the
wxPython Demo.

The wx interface is the same but you don't need to compile your code to
see how it works which is a big advantage - you can even make changes
from within the wxPython Demo are run them from there.

1. Install Python3 (unless you have it already) selecting the options to
add to the path.
2. Open a command window and enter: python -mpip install wxPython
3. type: wxDemo and select the option to download then save to the
default location (you may get an error the first time).
4. get prototyping from within the demo without having a compile/link cycle.

--
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect
those of my employer.

---
This email has been checked for viruses by AVG.
http://www.avg.com

David Bergman

unread,
Apr 21, 2018, 7:09:15 AM4/21/18
to wx-u...@googlegroups.com
I appreciate the suggestion but would that fix the issue I'm having?
Will using Python fix the nested splitter window issue?

My guess is that I may need to use boxSizer with the splitter or somehow
have the nested windows inherit parent sizes, but I'm not sure how.

compiling and linking isn't too bad an overhead right now.





On 4/21/2018 1:32 AM, Steve Barnes wrote:
>
> On 21/04/2018 03:43, David Bergman wrote:
>> Thanks for the reply.
>>
>> What is the wx version?
>> 3.1.0
>>
>> Which OS/toolkit?
>> Windows 8.1/SDK 10.0.15063.0
>>
>> What compile? (doubt it depends on that, but jus in case)
>> Visual Studio 2017, Visual C++ 14.1
>>
>>
> <SNIP>
>
> David,
>
> Can I strongly recommend prototyping in Python/wxPython & with the
> wxPython Demo.
>
> The wx interface is the same but you don't need to compile your code to
> see how it works which is a big advantage - you can even make changes
> from within the wxPython Demo are run them from there.
>
> 1. Install Python3 (unless you have it already) selecting the options to
> add to the path.
> 2. Open a command window and enter: python -mpip install wxPython
> 3. type: wxDemo and select the option to download then save to the
> default location (you may get an error the first time).
> 4. get prototyping from within the demo without having a compile/link cycle.
>


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

Vadim Zeitlin

unread,
Apr 21, 2018, 8:11:14 AM4/21/18
to wx-u...@googlegroups.com
On Fri, 20 Apr 2018 17:22:56 -0400 David Bergman wrote:

DB> I'm trying to make a graphic layout using multiple nested splitter
DB> windows. What I've done seems to work in that it does produce the
DB> desired initial result. However the sashes (or the panels/frames they
DB> outline) do not seem to resize properly.

It's really not difficult to mentally debug resizing of windows in
wxWidgets: all you have to know is that it always starts at the top and
propagates to the bottom (i.e. resizing a child window will never result in
resizing its parent automatically) and that resizing the window also
resizes its children: using the sizer generally speaking or using
control-specific resizing logic for particular container windows such as
wxFrame when it contains exactly one child (it resizes this child to fill
the entire frame client area), wxNotebook (it resizes its pages to fill the
notebook) or, indeed, wxSplitterWindow (it resizes its 2 subwindows to fill
it). This is all you need to know.

DB> A cut and paste snippet from the edited splitter window example is
DB> provided below.

The fundamental error here is that you use sizers with splitters, but this
doesn't really make sense. wxSplitterWindow already handles its resizing
very well on its own, using sizers with it just interferes with what it is
doing with, clearly, undesirable results. Just don't do it, having nested
windows is as simple as

auto splitMain = new wxSplitterWindow(this);
auto winLeft = new wxWindow(splitMain);

auto splitRight = new wxSplitterWindow(splitMain);
auto winUp = new wxWindow(splitRight);
auto winDown = new wxWindow(splitRight);
splitRight->SplitVertically(winUp, winDown);

splitMain->SplitHorizontally(winLeft, splitRight);

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

David Bergman

unread,
Apr 21, 2018, 8:51:53 AM4/21/18
to wx-u...@googlegroups.com
Vadim,

Thanks. I'll try this. The single split always works, it's the
multiple that don't (for me).
Also, I'm not expecting the parent to resize, the children were the issue.

Since I started with the sample code I don't remember if sizers were in
there or if I put them there.

David

David Bergman

unread,
Apr 22, 2018, 3:44:59 PM4/22/18
to wx-u...@googlegroups.com
Vadim,

I tried your suggestion and got the same problem. I think your
suggestion is how the code was originally written. I added boxSizers
after the fact in an attempt to fix it.

I will keep trying and if you can think of anything please let me know.

Thanks,

David


On 4/21/2018 8:11 AM, Vadim Zeitlin wrote:

Vadim Zeitlin

unread,
Apr 22, 2018, 6:16:52 PM4/22/18
to wx-u...@googlegroups.com
On Sun, 22 Apr 2018 15:44:48 -0400 David Bergman wrote:

DB> I tried your suggestion and got the same problem. I think your
DB> suggestion is how the code was originally written.

Well, yes, but it really should work if written like this. I.e. if you
just make the change as indicated to the splitter sample, you will see that
it does work. You probably have changed something else in your code, but I
don't know what could it be.

DB> I added boxSizers after the fact in an attempt to fix it.

You can put splitters inside sizers, of course, but you really shouldn't
put the splitter children inside any sizer -- they're already managed by
the splitter. Unfortunately, it's not simple to ensure that this can't
happen at wx API level...

DB> I will keep trying and if you can think of anything please let me know.

To be honest, I am not even sure what is the problem you're seeing
exactly. But if you've clearly identified it, you should be able to use the
mental model of how resizing works in wxWidgets that I gave in the previous
post to debug it and understand what needs to be done to fix it.

Good luck,

David Bergman

unread,
Apr 22, 2018, 7:43:29 PM4/22/18
to wx-u...@googlegroups.com
The original post had 2 screen shots which identify the problem.

I will try again starting from the original state of the sample and see
what happens.

Catalin

unread,
Apr 22, 2018, 10:51:10 PM4/22/18
to wx-u...@googlegroups.com
On Monday, 23 April 2018, 02:43:29 EEST, David Bergman wrote:
> The original post had 2 screen shots which identify the problem.

> I will try again starting from the original state of the sample and see
> what happens.

I suggest you start from Vadim's suggested code snippet. It should really be enough to give you the layout from your screenshots -- and that is (at least) _without_ any sizers or calls to SetSizer(), SetSize() or SetFocus().

Apart from all that, in your original code you also had a very important mistake: calling SetSizer() twice for m_splitter_2, with box2 and box3, which would actually destroy m_up. ...in which case the screenshots you posted cannot be the result of the code in the same email, can they?

HTH,
C

David Bergman

unread,
Apr 23, 2018, 6:59:16 AM4/23/18
to wx-u...@googlegroups.com
They are, I compiled that code, ran it and made the screen shots.
That I will state is absolutely true. 
I commented out all calls to sizer functions and recompiled and got the same result.
As far as the expectation that the call to SetSizer twice destroying m_up I cannot speak to that.
The reason I did it (and I was clearly mistaken) is that I was under the impression that each "box" needed to be resized when the parent is resized.  And that came from looking through examples on line when the original attempt didn't work.
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.
 
To unsubscribe, send email to wx-users+u...@googlegroups.com
or visit http://groups.google.com/group/wx-users


Virus-free. www.avast.com
Reply all
Reply to author
Forward
0 new messages