Columns auto-resize to size of QTableView - c++

I am new to Qt and I have just managed to make a QTableView work with my model. It has fixed 3 columns. When I open a window, it look ok but when i resize the window, the QTableView itself gets resized but columns' width remains the same. Is there any build-in way to make it work? I want columns to resize to fit the edges of QTableView every the the window gets resized.

This code equally stretches each column so that they fit the table's width.
table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
Docs:
QHeaderView::setSectionResizeMode
See resize modes here.

There is a header flag to ensure that the QTableView's last column fills up its parent if resized. You can set it like so:
table_view->horizontalHeader()->setStretchLastSection(true);
However, that does not resize the other columns proportionately. If you want to do that as well, you could handle it inside the resizeEvent of your parent thusly:
void QParent::resizeEvent(QResizeEvent *event) {
table_view->setColumnWidth(0, this->width()/3);
table_view->setColumnWidth(1, this->width()/3);
table_view->setColumnWidth(2, this->width()/3);
QMainWindow::resizeEvent(event);
}
QParent class is subclass of QMainWindow.

Widgets QTableView, QTreeView and their derived classes (such as QTableWidget) have this two usefull methods:
QHeaderView* horizontalHeader() const;
QHeaderView* verticalHeader() const;
If you open documentation for a class QHeaderView, you will find methods that set up appearance and behavior of row or column header for item views. You can resolve your problem by one of these methods:
void QHeaderView::stretchLastSection( bool stretch )
As Davy Jones mentioned.
Example:
QTableView *table = new QTableView();
table->horizontalHeader()->setStretchLastSection(true);
void QHeaderView::setResizeMode( ResizeMode mode )
As mode you can set QHeaderView::Stretch or QHeaderView::ResizeToContents.
Unfortunately this method have a drawback - after it's apply you will not be able to change size of columns (or rows) manually (in GUI) or programmatically.
Example:
QTableView *table = new QTableView();
table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);

In PyQt5 you can achieve this in your table_widget by doing:
header = table_widget.horizontalHeader()
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

Related

QListWidget rows overlaping each other

First of all I am apologizing for my English in advance. I am trying to display a custom widget in a QListWidget, but when more than one row is added, they are displayed on the same spot.
(source: minespeed200.de)
Settings of the QListWidget
alternateingRowColors:true
movement:Static
isWrapping:false
resizeMode:adjust
layoutMode:singePass
spacing:1
viewMode:listMode
i've already tried all of the possible settings for this values. if there is another importent one i've missed (i am fairly new to Qt) please tell me. Also the row colors seem to overlap too (the picture of my application below has 2 rows added), what tells me, that not only the widget's but the row's are overlapping each other entirely.
(source: minespeed200.de)
(source: minespeed200.de)
I am adding the rows with this code:
item=new QListWidgetItem();
QSize size(this->width(),this->height());
item->setSizeHint(size);
list->addItem(item);
list->setItemWidget(item,this);
Inside of the constructor of my custom widget class.
The issue was that i left the gridSize of my QListWidget at it's default value and the y component had to be set to the height of my widget i was displaying.
Adding:
list->setGridSize(QSize(0,this->sizeHint().height()));
fixed it.
I think you need this method.
list->QListWidget::setFlow(QListWidget::LeftToRight)
check here: https://doc.qt.io/archives/qt-4.8/qlistview.html#flow-prop

How to change the size of a QComboBox's QScrollBar?

I'm using a QComboBox with some items to the point that, when the widget that shows all available items in the QComboBox appears, only some of the items are visible with the other accesible through a QScrollBar.
The problem is that the QScrollBar is to thin and I want to make it larger. I did some research on the web and I did found some ways to change the QScrollBar's width (see references below), but the problem is that I simply can't find the method to access the QComboBox's QScrollBar.
So, given this problem, how can I do this change? (I guess you may either present me with a way that don't require me to access the QScrollBar or show how may I access it).
References:
vertical scrollbar width - Direct access and style
How to get scroll bar real width in Qt? - Again by pixlMetric (only access)
How to increase QTableWidget Vertical Scrollbar width? - Using stylesheet (a preferable method if there is a way to make it apply to all QScrollBars available in the project)
Other options are discussed here
Get the combobox's QAbstractItemView via view()
That class inherits from QAbstractScrollArea, thus inherits the verticalScrollBar method
e.g.
QAbstractItemView *qv = combobox.view();
QScrollBar *scrollbar = qv->verticalScrollBar();
// Adjust size via setStyleSheet or hint/width
The scroll bar isn't a member of the QComboBox class, it's a member of the underlying QAbstractItemView. Try something like the following (pseudo-code):
QListView* abby = new QListView();
QWidgetList list = abby->scrollBarWidgets(Qt::AlignRight);
for (auto itr = list.begin(); itr != list.end(); itr++)
{
(*itr)->setMinimumWidth(100);
}
QComboBox combo;
combo.setView(abby);
The scrollbarwidgets returns a widget list of the scroll bars for that alignment. You can then set the properties on the scroll bar pointers.

Qt QTableWidget Column resizing

I have a MainWindow with a QToolbar, QWidget and a QTabWidget. The layout is "Grid". However, my window is resizeable and since I have a layout it works well. But there is one problem, in my QTabWidget I have a QTableWidget with two columns (layout is also "Grid"). If I resize my whole window the QTableWidget resizes but not the columns.
For example Whenever I resize my window, my QTabWidget resizes and the QTableWidget in it too. Only the columns in my QTableWidget won't.
So... how can I resize them if my QTableWidget resizes?
Change the ResizeMode of the QHeaderView. For example, use:
horizontalHeader()->setResizeMode( 0, QHeaderView::Stretch );
to make the first column resize so the QTableWidget is always full.
Override the resizeEvent and set the widths of each column yourself when the QTableWidget has been resized.
To stretch last column:
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
To stretch column #n:
ui->tableWidget->horizontalHeader()->setSectionResizeMode(n, QHeaderView::Stretch);
The best solution for this, in Qt5 you have to use setSectionResizeMode instead of setResizeMode
tabv = QTableView()
tabv.horizontalHeader().setSectionResizeMode(QHeaderView::Stretch)
Also you can specify the Stretch mode when resizing
tabv.horizontalHeader().resizeSections(QHeaderView::Stretch)
ui->mytable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
If you want to resize just the last column:
ui->tableWidget->horizontalHeader()->setStretchLastSection(1);
You can change the "resize mode" of your columns or rows with the QHeaderView and the method QHeaderView::setResizeMode().
http://qt-project.org/doc/qt-4.8/qheaderview.html#setResizeMode
http://qt-project.org/doc/qt-4.8/qtableview.html#verticalHeader
http://qt-project.org/doc/qt-4.8/qtableview.html#horizontalHeader
In Qt5 you have to use setSectionResizeMode instead of setResizeMode
QTableWidget* myTable = new QTableWidet;
QHeaderView* header = myTable->horizontalHeader();
header->setSectionResizeMode(QHeaderView::Stretch);

Remove Widget from QGridLayout in Qt? [duplicate]

This question already has answers here:
Removing widgets from QGridLayout
(2 answers)
Closed 9 years ago.
I have a very basic doubt regarding QGridLayout.
For adding a widget in QGridLayout we give QWidget * that should be added along with the row & column no (some other args as well).
Now for removing a widget there is no function to remove a widget according to row & column no i.e. something like this:
int row, column;
gridObj->remove(row, column);
I think QGridLayout must be maintaining a sort of QList to store references of Widgets & there positions. So why is there no function for removing widgets by position only?
It only has 1 remove function for which we need to specify the reference of QWidget object.
If this is a limitation somehow then is there a workaround for this problem?
Maintaining a QList by myself is a solution but it is pretty tedious.
Thank You
I might be mistaken here, but from skimming the documentation, try this:
Get the QLayoutItem at the position (QGridLayout::itemAtPosition(row, column)).
Use the QLayoutItem to get the widget pointer (QLayoutItem::widget()).
Use the widget pointer to find the index of the widget in the QGridLayout (QLayout::indexOf(widgetPointer)).
Use the index to take ownership of the widget from the layout (QGridLayout::takeAt(index)).
Wrap it all in a convenience function?
I've always had trouble reordering widgets in layouts, removing widgets from layouts, and etc... Oftentimes, I just resort to deleting the layout and re-adding the widgets. =(
For removing a widget within a QGridLayout by layout position, you can simply use
layout->removeWidget(layout->itemAtPosition(row, column)->widget());
However, you have to note the following about it:
This code assumes that there actually is an item on the
specified position in the layout. If it isn't, itemAtPosition() will
return null. So you need to be sure about the position, or check it explicitly.
This code will remove the widget from the layout, but not delete it.
You have to put the widget back into a different layout or give the
widget a reasonable geometry yourself. If you don't, the widget will simply keep
visible at its current position. If you want the widget to be
destructed, you'll have to delete it explicitly after it has been
removed from the layout.
This code will only work for top-level widgets within the layout which have been
added with addWidget(). It won't work for nested layouts added with addLayout().
If you need to care about nested layouts as well, see
my answer about removing rows and columns from grid layouts.

Change table columns width on resizing window or splitter

Consider there is a QTablWidget and a QTextEdit. Both of them are in a horisontal QSplitte. Let the QTable widget has 2 columns.
The problem is to resize the table columns' width as you do resize operation by moving the splitter with mouse. Are there any options to may colums to be resized synchornosly with the table?
Thanks.
QHeaderView *header = ui->tableWidget->horizontalHeader();
header->setResizeMode(QHeaderView::Stretch);
This code sets all columns of ui->tableWidget to equal width and let it change automatically.
And take a look on QHeaderView description in docs, you can do almost anything you can imagine with table columns with this API.
Sad, but you can't set any stretch factor or smth., if you need relational column widths not to be equal, but you still can reimplement sizeHint() or resize sections when header's geometriesChanged fires.