WTreeView inside a WHBoxLayout
Added by Stas Magill 9 months ago
Hi,
I am trying to divide the available browser width equally between a WTreeView and some other widget (WTextArea in this simplified example). I am adding the tree view to a WHBoxLayout together with another widget and setting the stretch factors for both to 1. The tree view however always seems to take up all the available width (see screenshot). If I replace the tree view with another widget, then everything gets laid out as expected. Example code follows. Has anyone got any suggestions for how to get this working?
Thanks.
class WtTestApp : public WApplication
{
public:
WtTestApp(const WEnvironment& env) :
WApplication(env)
{
WStandardItemModel* model= new WStandardItemModel(0, 1);
model->appendRow(new WStandardItem("Row 1"));
model->appendRow(new WStandardItem("Row 2"));
model->appendRow(new WStandardItem("Row 3"));
WTreeView* tv= new WTreeView();
tv->setModel(model);
WHBoxLayout* l= new WHBoxLayout(root());
l->addWidget(tv, 1);
l->addWidget(new WTextArea(), 1);
}
};
Example.jpg (22.2 KB)
Replies (5)
RE: WTreeView inside a WHBoxLayout - Added by Wim Dumon 9 months ago
Hello Stas,
My two suggestions:
1. retry with a recent git version of Wt (there were some bugs fixed recently)
2. give your WTreeView a smaller size (though I don't think this is necessary)
BR,
Wim.
RE: WTreeView inside a WHBoxLayout - Added by Stas Magill 9 months ago
Thanks very much Wim. The latest git version does indeed fix the problem that I've illustrated. Unfortunately my example was a very simplified version of a much more complex layout, and that still goes wrong. By trying to reduce my full site to the point where it starts working, I've found another problem. It looks like setting a border for a tree view control causes confusion for a horizontal layout manager. Could you please try the code below? Every time I press the "Refresh" button, the tree view expands horizontally and squeezes the group box. If you delete the line that sets the border, then the example works fine! Strange stuff.
#include <Wt/WApplication>
#include <Wt/WHBoxLayout>
#include <Wt/WStandardItem>
#include <Wt/WStandardItemModel>
#include <Wt/WTreeView>
#include <Wt/WGroupBox>
#include <Wt/WPushButton>
using namespace std;
using namespace Wt;
class WtTestApp : public WApplication
{
public:
WStandardItemModel* m_model;
bool m_dataset;
WtTestApp(const WEnvironment& env) :
WApplication(env),
m_dataset(false)
{
m_model= new WStandardItemModel(0, 1);
WTreeView* tv;
tv= new WTreeView();
tv->decorationStyle().setBorder(WBorder(WBorder::Solid, 1));
tv->setModel(m_model);
WGroupBox* groupBox= new WGroupBox("Group");
WPushButton* button= new WPushButton("Refresh", groupBox);
button->clicked().connect(this, &WtTestApp::refresh);
WHBoxLayout* l= new WHBoxLayout(root());
l->setContentsMargins(0, 0, 0, 0);
l->addWidget(tv, 1);
l->addWidget(groupBox, 1);
refresh();
}
void refresh(void)
{
m_model->clear();
if (m_dataset)
{
m_model->appendRow(new WStandardItem("Row 4"));
m_model->appendRow(new WStandardItem("Row 5"));
m_model->appendRow(new WStandardItem("Row 6"));
m_model->setHeaderData(0, Horizontal, boost::any(string("Data 2")));
}
else
{
m_model->appendRow(new WStandardItem("Row 1"));
m_model->appendRow(new WStandardItem("Row 2"));
m_model->appendRow(new WStandardItem("Row 3"));
m_model->setHeaderData(0, Horizontal, boost::any(string("Data 1")));
}
m_dataset= !m_dataset;
}
};
WApplication* createApp(const WEnvironment& env)
{
return new WtTestApp(env);
}
int main(int argc, char *argv[])
{
return WRun(argc, argv, &createApp);
}
RE: WTreeView inside a WHBoxLayout - Added by Stas Magill 9 months ago
I've found a second cause for the same problem (ie tree view expanding horizontally). If I remove the border from the previous example, but have data that alternates between needing a vertical scrollbar in the treeview and not needing one, then the problem comes back. The code is very similar, but I've added an extra top level container which restricts the height of the layout and of course made one set of data contain lots of rows. Please let me know if you need the code.
Thanks again.
RE: WTreeView inside a WHBoxLayout - Added by Wim Dumon 9 months ago
Hello Stas,
Can you make a bug report for this (click 'New Issue'), and assign it to Koen?
Thank you,
Wim.
RE: WTreeView inside a WHBoxLayout - Added by Stas Magill 8 months ago
Hi Koen and Wim,
This has been raised as bug #1409, but has not yet been targeted for any version. There has been a mention of a possible release at the end of the month. Is this bug fix likely to be included? It's making part of our site unusable, so either a fix or at least some sort of a workaround would be great.
The previous example code actually works with the version taken from the git today, so just setting the border no longer causes a problem with updates. However, if updates alternate between needing a scrollbar and not needing one, then the tree view still expands. My test code is below.
Thanks.
#include <Wt/WApplication>
#include <Wt/WContainerWidget>
#include <Wt/WHBoxLayout>
#include <Wt/WStandardItem>
#include <Wt/WStandardItemModel>
#include <Wt/WTreeView>
#include <Wt/WGroupBox>
#include <Wt/WPushButton>
using namespace std;
using namespace Wt;
class WtTreeViewApp : public WApplication
{
public:
WStandardItemModel* m_model;
bool m_dataset;
WtTreeViewApp(const WEnvironment& env) :
WApplication(env),
m_dataset(false)
{
m_model= new WStandardItemModel(0, 1);
WTreeView* tv;
tv= new WTreeView();
tv->setModel(m_model);
WGroupBox* groupBox= new WGroupBox("Group");
WPushButton* button= new WPushButton("Refresh", groupBox);
button->clicked().connect(this, &WtTreeViewApp::refresh);
WContainerWidget* con= new WContainerWidget(root());
con->setMaximumSize(WLength::Auto, 200);
WHBoxLayout* l= new WHBoxLayout(con);
l->setContentsMargins(0, 0, 0, 0);
l->addWidget(tv, 1);
l->addWidget(groupBox, 1);
refresh();
}
void refresh(void)
{
m_model->clear();
if (m_dataset)
{
m_model->appendRow(new WStandardItem("Row 4"));
m_model->appendRow(new WStandardItem("Row 5"));
m_model->appendRow(new WStandardItem("Row 6"));
m_model->appendRow(new WStandardItem("Row 7"));
m_model->appendRow(new WStandardItem("Row 8"));
m_model->appendRow(new WStandardItem("Row 9"));
m_model->appendRow(new WStandardItem("Row 10"));
m_model->appendRow(new WStandardItem("Row 11"));
m_model->appendRow(new WStandardItem("Row 12"));
m_model->appendRow(new WStandardItem("Row 13"));
m_model->appendRow(new WStandardItem("Row 14"));
m_model->appendRow(new WStandardItem("Row 15"));
m_model->setHeaderData(0, Horizontal, boost::any(string("Data 2")));
}
else
{
m_model->appendRow(new WStandardItem("Row 1"));
m_model->appendRow(new WStandardItem("Row 2"));
m_model->appendRow(new WStandardItem("Row 3"));
m_model->setHeaderData(0, Horizontal, boost::any(string("Data 1")));
}
m_dataset= !m_dataset;
}
};
(1-5/5)