QTreeWidget - width of column with widget - qt

I have QTreeWidget with two columns. The first column is the text, and the second is QPushButton. I can not specify the size of buttons and the size of the second column. When you try to set the size of the column of content, the second column disappears. How to change the width of the second column?
tree_widget_->setColumnCount(2);
tree_widget_->header()->resizeSection(1, 10);
tree_widget_->header()->setStretchLastSection(false);
tree_widget_->header()->setResizeMode(0,QHeaderView::Stretch);
tree_widget_->topLevelItem(4)->addChild( wiop = new QTreeWidgetItem(QStringList() << QString( "Расстояние: %1 км" ).arg( range ) ) );
tree_widget_->setItemWidget(tree_widget_->topLevelItem(4)->child(0),1,range_plot_button_ = new QPushButton("График",tree_widget_));
range_plot_button_->resize(10,10);

tree_widget_->setColumnWidth(1, 10) should do what you wanted.
When you assign QPushButton to QTreeWidget as a top level item the QTreeWidget object usualy assigned as a parent of this button, so all geometry of that button is handled by it's parent.
Take a look at docs.
If you want your push button to have it's own geometry with layouts (within column) you can make blank widget, set it to TreeWidget as an item and make your push button to be a child of that blank widget with all conveniences of layouts in Qt.

I try setColumnWidth, but it is not work.
Later I try tree_widget_->header()->setResizeMode(1,QHeaderView::ResizeToContents);
and it is work!

Related

How to autofit widget size and position to a cell in QTreeWidget?

I pragrammaticaly create a QTreeWidget.
Then I pragrammaticaly add some items.
Then I add two QLabel widgets to two items (QTreeWidgetItem) by
myTree->setItemWidget(item1, 0, myLabel1);
myTree->setItemWidget(item2, 0, myLabel2);
And then I try to resize the row of the item pragrammaticaly.
If I use an
item1->setSizeHint(0, QSize(myWidth, myHeight) );
the row chaged. But myLabel1 is not.
If I use an
item1->setSizeHint(0, QSize(myWidth, myHeight) );
myLabel->resize(myWidth, myHeight);
everething is ok but the row of myLabel2 mis adjusting to label by position.
Can I do something to auto-adjusting a widget (by size and position) to a cell of QTreeWidget?
P.S. After any resizing of tree (resize by width or expand/collapse node) widgets updates correctly.
In view of the fact that autofit start after resizing QTreeWidget, there is some method inside that resize widgets in cells.
So I opened QTreeWidget description (https://doc.qt.io/qt-5/qtreewidget.html) and red all of Public Functions and Public Slots. When I did not find any useful function I looked at a parent class (QTreeView). And found
myTree->resizeColumnToContent(0);
Call resizeColumnToContent after resizing any row in a QTreeWidget and widgets will be always fit to cells.
P.S. I am the OP.
you can try adding/updating a widget as an item, for example:
QWidget* wdg = new QWidget;
QPushButton* btIcon = new QPushButton();
QLabel* lb = new QLabel();
QHBoxLayout* layout = new QHBoxLayout(wdg);
layout->addWidget(btIcon);
layout->addWidget(lb);
layout->setAlignment( Qt::AlignCenter );
wdg->setLayout(layout);
myTree->setItemWidget(item1, 0, wdg);
Or just fill the tree with widgets

How change row color with Null items?

I want to change color of the row with NULL items (I didn't do setData() or setItem()) in QTableWidget. How to do this?
To have full control over the items, I would just drop in an item, and then set the background color:
Fill the row with QTableWidgetItem's and then you can change the background color.
QTableWidgetItem *newItem = new QTableWidgetItem("");
tableWidget->setItem(row, column, newItem);
QColor color( Qt::red );
tableWidget->item( row, column )->setBackgroundColor( color );
That is the main way that I have formatted any cells in the past.
QStyleSheets
In the documentation for QStyleSheets, QTableView and QTableWidget share the same kind of properties:
http://qt-project.org/doc/qt-4.8/stylesheet-examples.html#customizing-qtableview
http://qt-project.org/doc/qt-4.8/stylesheet-reference.html#alternate-background-color-prop
http://qt-project.org/doc/qt-4.8/stylesheet-reference.html#item-sub
It should work with the table and rows, even if it isn't full of items.
Hope that helps!

Need to display the widgets inside my QListWidget with an offset, basically shifted a bit to the right

I have a panel.ui file done using QTDesigner. It's a QFrame class, rectangular shape with few labels on it. And I have a QListWidget class where I insert 3 instances of the panel.ui.
I create a QListWidgetItem and then use List->SetItemWidget(..) to populate my list.
The Result is a list filled with three panels. I was also able to move the panels inside the list using dragDropMode internalMove.
I also tested the ability to shift the panels a bit to the right when I click on them and that worked:
in procedure List::mousePressEvent(QMouseEvent *event)
Panel *child = static_cast<Panel*>(childAt(event->pos()))
...
int y= child->pos().y();
int x = child->pos().x();
child->move (x +10, y); `
Problem: When I run the app and display the list, I want all the panels to be displayed with that 10 offset to the right. So in the List constructor and inside the loop after this->setItemWidget(myPanelItem, myPanel); I try using myPanel->move() like above but it doesn't seem to work.
I run the app, the panels are displayed without my offset ( not sure why?) but when I click on one, it shifts.
move() won't work reliably since the widgets are in a layout. (Well, not a layout as in a QLayout, but the effect is comparable: When any metric in your application changes, e.g. you resize or scroll the list, the widgets are repositioned by the list widget.)
What you can do is wrap your actual widget in a container widget with a layout margin:
QWidget* wrapIntoContainerForOffset(QWidget* widget, int offset /*in pixels*/) {
QWidget* container = new QWidget;
QHBoxLayout* layout = new QLayout(container);
layout->setContentsMargins(/*left=*/ offset, /*others=*/ 0, 0, 0);
layout->addWidget(widget);
return container;
}
Then you add these containers to the listwidget instead.
Have You tried StyleSheets. The QListWidget supports Box model( http://doc.qt.digia.com/qt/stylesheet-customizing.html#box-model ). So You may want to try playing around with margins in the stylesheets.
Style sheet reference: http://doc.qt.digia.com/qt/stylesheet-reference.html

How to set an image for a row?

I want to add text (at the beginning of a row) and an image at the end of the row.
I can set the text but how to set an image at the end of the row item in QTreeWidgetItem?
Just set for example two columns in QTreeWidget and then set text in first one and icon in second one:
QTreeWidgetItem *newItem = new QTreeWidgetItem;
newItem->setText(0, "Something");
newItem->setIcon(1, QIcon("Path to your icon"));
myTreeWidget->addTopLeveItem(newItem);
Or instread of setting icon you can just set foreground:
newItem->setForeground(QBrush(QPixmap("Path to your image")));
which may be better for your problem.

fixing child layout/widget position in QT

I wanted to know whether is there any way of fixing child layouts within a parent layout. For example...
QVBoxLayout *vbox = new QVBoxLayout;
// adding pushbuttons/layouts...
vbox->addWidget(one);
vbox->addWidget(two);
vbox->addWidget(three);
vbox->addWidget(four);
Now this ends up as four buttons/layouts in a vertical layout in the sequence that they are added. But if I remove buttons/layouts "one", "two" and "three"...
vbox->removeWidget(one);
vbox->removeWidget(two);
vbox->removeWidget(three);
After doing this, the pushbutton "four" will move up the layout as you remove widgets on top of "four". I don't want this to happen.
Is there any way that even if I remove the widget/layout on top, I need that last widget/layout to stay where it is currently.
How do I achieve this ?
UPDATE: Well I was experimenting and I was kind of able to achieve what I wanted using QGridLayout. Here is the code, but I am using QGridLayout instead of QVBoxLayout.
connect(one,SIGNAL(clicked()),this,SLOT(remove_btns()));
g = new QGridLayout(this);
g->addWidget(one,0,0,1,2);
g->addWidget(two,1,0,1,2);
g->addWidget(three,2,0,1,2);
g->addWidget(four,3,0,1,2,Qt::AlignBottom);
setLayout(g);
If I delete the above three buttons, the fourth one stays where it is, because of QT::AlignBottom , it does not work without that thing.
Here is the SLOT remove_btns()
void test::remove_btns()
{
g->removeWidget(one);
g->removeWidget(two);
g->removeWidget(three);
delete one;
delete two;
delete three;
}
When I click "one", top three buttons vanish, and the fourth one stays where it is. But it does not work if I don't give the QT::AlignBottom . Also, these alignment things are a mystery to me, I am unable to find how exactly they work.
This is definitely NOT an answer..., because I don't understand how it worked :P
If you are immediately replacing the widgets you removed, you can always insert your new widgets by index.
void insertWidget ( int index, QWidget * widget, int stretch = 0, Qt::Alignment alignment = 0 )
Yes, just hide the widgets instead of removing them:
one->hide();
two->hide();
three->hide();
If you really have to remove the widgets, perhaps you can replace them with some lightweight widget like a QLabel with no text.

Resources