How to stretch the child nodes of QTreeView
-
Here's how it looks by default:
The root nodes, ie. table, view, index and trigger takes the whole space to their right side BUT the child nodes don't. I've triedtree->resizeColumnToContents(1)
after populating the treeview BUT that doesn't work. Here's how I added these in theQTreeView
:tree = new QTreeView(this); tree->setContentsMargins(0,0,0,0); tree->setHeaderHidden(true); ... auto model = new QStandardItemModel(tree); model->setColumnCount(2); QSqlQuery query("SELECT * FROM sqlite_master"); if(query.exec()){ QStandardItem *parent; QString name; while (query.next()) { if(query.value(0).toString() != name){ QIcon icon; name = query.value(0).toString(); if(name == "table") icon = QIcon(":/table.svg"); else if(name == "view") icon = QIcon(":/view.svg"); else if(name == "trigger") icon = QIcon(":/trigger.svg"); else icon = QIcon(":/index.svg"); parent = new QStandardItem(icon, name); parent->setFont(QFont(parent->font().family(), -1, QFont::Bold, false)); model->appendRow(parent); } auto child = new QStandardItem(query.value(1).toString()); parent->appendRow(child); } } db.close(); tree->setModel(model); //tree->resizeColumnToContents(1);
I want the child node also to take the entire space to its right side so that the whole text is visible when I expand root nodes. Am I doing it in proper way or there's some shortcut to achieve the same?
-
@mpergand, I don't want to show the headers with splitter on top and without that I can't change the state manually. like I did in the GIF example above.
@Emon-Haque said in How to stretch the child nodes of QTreeView:
@mpergand, I don't want to show the headers with splitter on top and without that I can't change the state manually. like I did in the GIF example above.
Did you mean this?
tree->header()->setSectionResizeMode(0, QHeaderView::Stretch);
-
@mpergand, It's inside a QSplitter and that splitter is inside a QVBoxLayout. The QWidget that contains the QTreeView is inside a QStackedWidget and that StackedWidget is the centralWidget of the QMainWindow.
-
I think you have to add a layout to the widget containing the treeview for this one to expand.
To visualize the actual size of the treeview, you can do:
tree->setFrameShape(QFrame::Box);To verify if your interface is correct, you can try to reproduce it in the Designer and see if it works as you expected.
-
I think you have to add a layout to the widget containing the treeview for this one to expand.
To visualize the actual size of the treeview, you can do:
tree->setFrameShape(QFrame::Box);To verify if your interface is correct, you can try to reproduce it in the Designer and see if it works as you expected.
@mpergand, I've put these 3 segments in a
QWidget
named QueryWidget. On the left where the TreeView is, called ObjectView and on the right the CodeEditor and in bottom a textbox, and for now everything is in its constructor:QueryWidget::QueryWidget(QWidget *parent) : QWidget(parent) { objects = new ObjectsView(this); codeEditor = new CodeEditor(this); auto textBox = new QTextEdit(this); auto split1 = new QSplitter(Qt::Horizontal, this); auto split2 = new QSplitter(Qt::Vertical, this); split1->addWidget(objects); split1->addWidget(codeEditor); QSizePolicy obj(QSizePolicy::Preferred, QSizePolicy::Preferred); QSizePolicy cod(QSizePolicy::Preferred, QSizePolicy::Preferred); obj.setHorizontalStretch(1); cod.setHorizontalStretch(3); objects->setSizePolicy(obj); codeEditor->setSizePolicy(cod); split2->addWidget(split1); split2->addWidget(textBox); QSizePolicy sp1(QSizePolicy::Preferred, QSizePolicy::Preferred); QSizePolicy txt(QSizePolicy::Preferred, QSizePolicy::Preferred); sp1.setVerticalStretch(2); txt.setVerticalStretch(1); split1->setSizePolicy(sp1); textBox->setSizePolicy(txt); auto vLay = new QVBoxLayout(this); vLay->addWidget(split2); }
in the ObjectView's constructor I've a toolBar and treeview in QVBoxlayout:
ObjectsView::ObjectsView(QWidget *parent) : QWidget(parent) { auto toolBar = new QToolBar(this); tree = new QTreeView(this); tree->setHeaderHidden(true); auto attach = new QAction(QIcon(":/database-plus.svg"), "attach database", this); toolBar->addAction(attach); connect(attach, &QAction::triggered, this, &ObjectsView::openFileDialog); auto layout = new QVBoxLayout(this); layout->setContentsMargins(0,0,0,0); layout->addWidget(toolBar); layout->addWidget(tree); setLayout(layout); }
and in the MainWindow's constructor I've put the QueryWidget in the StackWidget like this:
Window::Window(QWidget *parent) : QMainWindow(parent) { stack = new QStackedWidget(this); queryWidget = new QueryWidget(stack); tableWidget = new TableWidget(stack); stack->addWidget(queryWidget); stack->addWidget(tableWidget); setCentralWidget(stack); .... }
I've tried the
tree->setFrameShape(QFrame::Box)
BUT there's no apparent difference in the Window. -
I've tried the tree->setFrameShape(QFrame::Box) BUT there's no apparent difference in the Window.
It doesn't change anything, it draws a box around the treeview.
Look at this splitter
The frame on the left doesn't expand because the parent widget has no layout.
[EDIT]
auto layout = new QVBoxLayout(this); layout->setContentsMargins(0,0,0,0); layout->addWidget(toolBar); layout->addWidget(tree); setLayout(layout);
Your code seems correct.
If you don't add the toolbar, what happens ?
Do you see the frame box around the tree ? -
I've tried the tree->setFrameShape(QFrame::Box) BUT there's no apparent difference in the Window.
It doesn't change anything, it draws a box around the treeview.
Look at this splitter
The frame on the left doesn't expand because the parent widget has no layout.
[EDIT]
auto layout = new QVBoxLayout(this); layout->setContentsMargins(0,0,0,0); layout->addWidget(toolBar); layout->addWidget(tree); setLayout(layout);
Your code seems correct.
If you don't add the toolbar, what happens ?
Do you see the frame box around the tree ?@mpergand, it shows the border around the treeview without
setFrameShape
. See, it takes up the remainder of theQVboxLayout
and shows black/grey border around white space allocated for theQTreeView
:
-
You may set a minimum width for the first column or save/restore the state of the header,
see QHeaderView :QByteArray QHeaderView::saveState() const
Saves the current state of this header view.
To restore the saved state, pass the return value to restoreState().
This function was introduced in Qt 4.3.
See also restoreState(). -
You may set a minimum width for the first column or save/restore the state of the header,
see QHeaderView :QByteArray QHeaderView::saveState() const
Saves the current state of this header view.
To restore the saved state, pass the return value to restoreState().
This function was introduced in Qt 4.3.
See also restoreState().@mpergand, I don't want to show the headers with splitter on top and without that I can't change the state manually. like I did in the GIF example above.
-
@mpergand, I don't want to show the headers with splitter on top and without that I can't change the state manually. like I did in the GIF example above.
@Emon-Haque said in How to stretch the child nodes of QTreeView:
@mpergand, I don't want to show the headers with splitter on top and without that I can't change the state manually. like I did in the GIF example above.
Did you mean this?
tree->header()->setSectionResizeMode(0, QHeaderView::Stretch);
-
@Emon-Haque said in How to stretch the child nodes of QTreeView:
@mpergand, I don't want to show the headers with splitter on top and without that I can't change the state manually. like I did in the GIF example above.
Did you mean this?
tree->header()->setSectionResizeMode(0, QHeaderView::Stretch);
@kshegunov, exactly. Now with header hidden, columns stretches automatically as I move the splitter.
Thanks