wxGrid + wxButton in wxFlexGridSizer

Are you writing your own components and need help with how to set them up or have questions about the components you are deriving from ? Ask them here.
Dobias
In need of some credit
In need of some credit
Posts: 9
Joined: Tue Sep 15, 2009 9:29 am

wxGrid + wxButton in wxFlexGridSizer

Post by Dobias » Tue Sep 15, 2009 9:42 am

Hello dear Community,

i have a problem with my UI design with wxWidgets:
I want to have a table (wxGrid) and four buttons below it on a panel.
If the table becomes too long so that it does not fit into the window any more, i want it to have scrollbars into the necessary direction.
The buttons should be visible in any case.

My actual code in the constructor of my wxPanel-child-class looks like this:

Code: Select all

wxGridSizer* buttonSizer = new wxGridSizer( 1, 4, 10, 10 );
		
buttonSizer->Add( Button1 );
buttonSizer->Add( Button2 );
buttonSizer->Add( Button3 );
buttonSizer->Add( Button4 );

wxFlexGridSizer* tableFlexGridSizer = new wxFlexGridSizer( 2, 1, 10, 10 );
tableFlexGridSizer->AddGrowableRow( 1 );
tableFlexGridSizer->Add( LoadGrid, 1, wxGROW );
tableFlexGridSizer->Add( buttonSizer, 1, wxGROW );

tableFlexGridSizer->Fit( this );
tableFlexGridSizer->SetSizeHints( this );

SetSizer( tableFlexGridSizer );
Unfortunately it looks like this:
picture 1:
Image
The white area right of the table should not be there.

picture 2:
Image
The table should be not that high so that the buttons are visible.

It would be great if you could help me, because i don't get to my goal in spite of having tried much on my own and read some tutorials.

many thanks in advance
Dobias

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Tue Sep 15, 2009 3:51 pm

I'd envision something simpler :


Code: Select all

+-----------------------+
|  vertical box sizer   |
|                       |
|         GRID          |
|                       |
|                       |
|+--------------------+ |
|| h box sizer + btns | |
|+--------------------+ |
+-----------------------+

You'd give the grid a proportion of 1 (scale) + wxEXPAND, and the bottom sizr a proportion of 0

This way, even if the window is made smaller, the buttons would still appear at the bottom.
"Keyboard not detected. Press F1 to continue"
-- Windows

Dobias
In need of some credit
In need of some credit
Posts: 9
Joined: Tue Sep 15, 2009 9:29 am

Post by Dobias » Wed Sep 16, 2009 6:48 am

Hi Auria,

thank you for the suggestion, but i can't get your version to work either.

Not it looks like this:
Image

My code in the constructor of my wxPanel-child-class now looks like this:

Code: Select all

wxBoxSizer* horizontalBoxSizer = new wxBoxSizer( wxHORIZONTAL );
		
horizontalBoxSizer->Add( Button1 );
horizontalBoxSizer->Add( Button2 );
horizontalBoxSizer->Add( Button3 );
horizontalBoxSizer->Add( Button4 );

wxBoxSizer* verticalBoxSizer = new wxBoxSizer( wxVERTICAL );
verticalBoxSizer->Add( LoadGrid, 1, wxEXPAND );
verticalBoxSizer->Add( horizontalBoxSizer, 0 );

verticalBoxSizer->Fit( this );
verticalBoxSizer->SetSizeHints( this );

SetSizer( verticalBoxSizer );
What am i doing wrong? :-)

catalin
Moderator
Moderator
Posts: 1521
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Post by catalin » Wed Sep 16, 2009 9:10 am

Code: Select all

wxBoxSizer* horizontalBoxSizer = new wxBoxSizer( wxHORIZONTAL );
		
horizontalBoxSizer->Add( Button1, 1 );
horizontalBoxSizer->Add( Button2, 1 );
horizontalBoxSizer->Add( Button3, 1 );
horizontalBoxSizer->Add( Button4, 1 );

wxBoxSizer* verticalBoxSizer = new wxBoxSizer( wxVERTICAL );
verticalBoxSizer->Add( LoadGrid, 1, wxEXPAND );
verticalBoxSizer->Add( horizontalBoxSizer, 0, wxEXPAND );

SetSizer( verticalBoxSizer );
verticalBoxSizer->Layout();
verticalBoxSizer->Fit( this );

//there should be no need for this:
//verticalBoxSizer->SetSizeHints( this ); 
How's that?

Dobias
In need of some credit
In need of some credit
Posts: 9
Joined: Tue Sep 15, 2009 9:29 am

Post by Dobias » Wed Sep 16, 2009 11:04 am

Thank you. That is better but still not perfect.

The good thing is, that the buttons stay visible now when the grid is forced to have scrollbars.
Image

The drawback is, that the unused space is filled with white color (which i guess comes from the grid.
Image

Do you know how i can get rid of this?

catalin
Moderator
Moderator
Posts: 1521
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Post by catalin » Wed Sep 16, 2009 11:10 am

Dobias wrote:the unused space is filled with white color (which i guess comes from the grid.
Do you know how i can get rid of this?
wxGrid::AutoSizeColumn[s]

Dobias
In need of some credit
In need of some credit
Posts: 9
Joined: Tue Sep 15, 2009 9:29 am

Post by Dobias » Wed Sep 16, 2009 11:48 am

Ok, now i have

Code: Select all

LoadGrid->AutoSizeColumns();

wxBoxSizer* horizontalBoxSizer = new wxBoxSizer( wxHORIZONTAL );
               
horizontalBoxSizer->Add( Button1, 1 );
horizontalBoxSizer->Add( Button2, 1 );
horizontalBoxSizer->Add( Button3, 1 );
horizontalBoxSizer->Add( Button4, 1 );

wxBoxSizer* verticalBoxSizer = new wxBoxSizer( wxVERTICAL );
verticalBoxSizer->Add( LoadGrid, 1, wxEXPAND );
verticalBoxSizer->Add( horizontalBoxSizer, 0, wxEXPAND );

SetSizer( verticalBoxSizer );
verticalBoxSizer->Layout();
verticalBoxSizer->Fit( this ); 
but the result is still the same.

catalin
Moderator
Moderator
Posts: 1521
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Post by catalin » Wed Sep 16, 2009 11:56 am

Dobias wrote:

Code: Select all

LoadGrid->AutoSizeColumns();
but the result is still the same.
The world would have been way ahead if people had actually read the docs.. :)

Call LoadGrid->AutoSizeColumns( false );

Dobias
In need of some credit
In need of some credit
Posts: 9
Joined: Tue Sep 15, 2009 9:29 am

Post by Dobias » Wed Sep 16, 2009 12:03 pm

I'm very sorry, but

Code: Select all

LoadGrid->AutoSizeColumns( false );

wxBoxSizer* horizontalBoxSizer = new wxBoxSizer( wxHORIZONTAL );
               
horizontalBoxSizer->Add( Button1, 1 );
horizontalBoxSizer->Add( Button2, 1 );
horizontalBoxSizer->Add( Button3, 1 );
horizontalBoxSizer->Add( Button4, 1 );

wxBoxSizer* verticalBoxSizer = new wxBoxSizer( wxVERTICAL );
verticalBoxSizer->Add( LoadGrid, 1, wxEXPAND );
verticalBoxSizer->Add( horizontalBoxSizer, 0, wxEXPAND );

SetSizer( verticalBoxSizer );
verticalBoxSizer->Layout();
verticalBoxSizer->Fit( this );
produces the same result (much white space).

catalin
Moderator
Moderator
Posts: 1521
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Post by catalin » Wed Sep 16, 2009 12:23 pm

How do you create the Grid?

Dobias
In need of some credit
In need of some credit
Posts: 9
Joined: Tue Sep 15, 2009 9:29 am

Post by Dobias » Thu Sep 17, 2009 7:54 am

I've reduced the problem to a minimal example to make things easier.

It looks like this:

Code: Select all

#include "wx/wx.h" 
#include "wx/grid.h"

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

class MyFrame: public wxFrame
{
public:
    MyFrame( const wxString& title, const wxPoint& pos, const wxSize& size );
};

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame( "Dobiasds SizerTest", wxPoint( -1, -1 ), wxSize( -1, -1 ) );
    frame->Show( true );
    return TRUE;
} 

MyFrame::MyFrame( const wxString& title, const wxPoint& pos, const wxSize& size )
: wxFrame( (wxFrame*) NULL, -1, title, pos, size )
{
	wxGrid* grid = new wxGrid( this, wxID_ANY );
	grid->CreateGrid( 20, 10 );
	grid->AutoSizeColumns( false );

	wxButton* button1 = new wxButton( this, wxID_ANY, "button1" );
	wxButton* button2 = new wxButton( this, wxID_ANY, "button2" );
	wxButton* button3 = new wxButton( this, wxID_ANY, "button3" );
	wxButton* button4 = new wxButton( this, wxID_ANY, "button4" );

	wxBoxSizer* horizontalBoxSizer = new wxBoxSizer( wxHORIZONTAL );

	horizontalBoxSizer->Add( button1, 1 );
	horizontalBoxSizer->Add( button2, 1 );
	horizontalBoxSizer->Add( button3, 1 );
	horizontalBoxSizer->Add( button4, 1 );

	wxBoxSizer* verticalBoxSizer = new wxBoxSizer( wxVERTICAL );
	verticalBoxSizer->Add( grid, 1, wxEXPAND );

	verticalBoxSizer->Add( horizontalBoxSizer, 0, wxEXPAND );

	SetSizer( verticalBoxSizer );
	verticalBoxSizer->Layout();
	verticalBoxSizer->Fit( this ); 
}
I do have the same problems here.

catalin
Moderator
Moderator
Posts: 1521
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Post by catalin » Thu Sep 17, 2009 9:26 am

hmm.. I checked the wxGrid sources a bit and it seems that it should work if you call grid->AutoSize() (..same as grid->Fit()) at the end of MyFrame constructor, as it will add the remaining space to the last column.
But I did not test anything.

Dobias
In need of some credit
In need of some credit
Posts: 9
Joined: Tue Sep 15, 2009 9:29 am

Post by Dobias » Thu Sep 17, 2009 11:06 am

Ok, now i have

Code: Select all

#include "wx/wx.h" 
#include "wx/grid.h"

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

class MyFrame: public wxFrame
{
public:
    MyFrame( const wxString& title, const wxPoint& pos, const wxSize& size );
};

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame( "Dobiasds SizerTest", wxPoint( -1, -1 ), wxSize( -1, -1 ) );
    frame->Show( true );
    return TRUE;
} 

MyFrame::MyFrame( const wxString& title, const wxPoint& pos, const wxSize& size )
: wxFrame( (wxFrame*) NULL, -1, title, pos, size )
{
	wxGrid* grid = new wxGrid( this, wxID_ANY );
	grid->CreateGrid( 20, 10 );
	grid->AutoSizeColumns( false );

	wxButton* button1 = new wxButton( this, wxID_ANY, "button1" );
	wxButton* button2 = new wxButton( this, wxID_ANY, "button2" );
	wxButton* button3 = new wxButton( this, wxID_ANY, "button3" );
	wxButton* button4 = new wxButton( this, wxID_ANY, "button4" );

	wxBoxSizer* horizontalBoxSizer = new wxBoxSizer( wxHORIZONTAL );

	horizontalBoxSizer->Add( button1, 1 );
	horizontalBoxSizer->Add( button2, 1 );
	horizontalBoxSizer->Add( button3, 1 );
	horizontalBoxSizer->Add( button4, 1 );

	wxBoxSizer* verticalBoxSizer = new wxBoxSizer( wxVERTICAL );
	verticalBoxSizer->Add( grid, 1, wxEXPAND );

	verticalBoxSizer->Add( horizontalBoxSizer, 0, wxEXPAND );

	SetSizer( verticalBoxSizer );
	verticalBoxSizer->Layout();
	verticalBoxSizer->Fit( this );

	grid->AutoSize();
}
but the result is still the same.
It does not even blow the last colums up to the free space. But that is anyway not what i want.
Seems like i have to read a bit more about sizers and spacers and create something more nested.
Thank you nevertheless.

catalin
Moderator
Moderator
Posts: 1521
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Post by catalin » Thu Sep 17, 2009 11:21 am

Dobias wrote:Seems like i have to read a bit more about sizers and spacers and create something more nested.
Thank you nevertheless.
As I see it, this is not about sizers and spacers since the white space that you see is part of the wxGrid (see the grey area at the top - that is the [most obvious] proof).
So it behaves correctly when added to the sizer. There is a problem with resizing its columns thowgh - something internal to wxGrid.
My advice would be to check the sources for something that works different than the way you'd expect.

Anyway, good luck!

Dobias
In need of some credit
In need of some credit
Posts: 9
Joined: Tue Sep 15, 2009 9:29 am

Post by Dobias » Thu Sep 17, 2009 1:41 pm

Thanks.
The sizers-and-spacers-solution would be to nest the grid into spacers so that when the window grows the grid takes its optimal size as soon as posible but further space will be given to the spacer aside. But I don't know if this is actually possible. ;-)

Post Reply