While you answered your own question, it seems that you changed the behavior by removing the first table (moreover, changing the resize mode of the first column stretch doesn't have much to do with your issue). So I'm answering to your [edited] question, even if it's missing the part in which you added the buttons to the first table.
The main problem was that you were setting a column span too big for the second table:
self.grid.addWidget(self.button_table, 0, 0, 1, 1)
self.grid.addWidget(self.layer_table, 0, 1, 1, 3) # <- 3 columns!
self.grid.addWidget(self.graphWidget, 1, 0, 1, 4)
In the code above, you're telling the layout that the layer_table
will have a column span of 3 columns. Even if you are not actually using three columns, by doing this the layout thinks that the second table will (probably) occupy more space than the first.
Normally, a QGridLayout will use the columnStretch
property for that, but since by default the stretch is 0 for all columns and rows, it will use the span as a reference.
In fact, using the following:
self.grid.addWidget(self.button_table, 0, 0, 1, 1)
self.grid.addWidget(self.layer_table, 0, 1, 1, 1) # <- 1 column!
self.grid.addWidget(self.graphWidget, 1, 0, 1, 2)
is the same as this:
self.grid.addWidget(self.button_table, 0, 0, 1, 1)
self.grid.addWidget(self.layer_table, 0, 1, 1, 3) # <- 3 columns!
self.grid.addWidget(self.graphWidget, 1, 0, 1, 4)
self.grid.setColumnStretch(0, 1)
self.grid.setColumnStretch(1, 1)
In the first case, the column span is 1 (one widget, one column), and, since the two widgets are of the same type, they will use half of the available horizontal space. In the second, the column span of the right table is 3 (as in your code), but the stretch is 1 for both the first and second column, and 0 for the third and fourth, meaning that a widget that occupies the second, third and fourth column will have the same available space than a widget that occupies the first, thus obtaining the horizontal space equally divided between those two widgets.
col1 | col2 | col3 | col4
1 | 1 | 0 | 0
Since the second table occupies columns 2 to 4, it will have a stretch of 1 (1 + 0 + 0). Stretches are used by layouts to equally divide the space between widgets (considering their size hints, their minimum size hints, or their minimum/maximum size whenever they're set): the stretches are summed integer values, and then the layout uses the proportions between the sum and those values to resize widgets.
To ensure that the first table uses only the minimum space required to show its contents, you need to do the following:
- set the
sizeAdjustPolicy
(which is a property of every QAbstractScrollArea descendant, including every item view) to AdjustToContents
; this will make the table "tell" the layout that its size hint is based on its minimum contents;
- set the resize mode of the horizontal header to adjust all of its sections (as in columns) to their contents;
- set the horizontal size policy of the table to
Maximum
; the term "maximum" might be counterintuitive, but it means that the widget's size cannot be larger than its size hint; still, it could be shrunk if any other widget requires space (but not less than the minimumSizeHint
) so, alternatively, you could use Fixed
(meaning that it cannot even shrink), but it's usually better to allow widgets to be shrunk anyway if the layout is too crowded and the user requires to make the window smaller than it is;
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setGeometry(50, 50, 700, 1000)
self.home()
def home(self):
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.button_table = QTableWidget(self)
self.button_table.setRowCount(3)
self.button_table.setColumnCount(1)
# set the sizeHint of the table view (actually, its ancestor class,
# QAbstractScrollArea) to the minimum size required to show its contents
self.button_table.setSizeAdjustPolicy(self.button_table.AdjustToContents)
# set all sections of the horizontal headers to adjust themselves to
# their contents
self.button_table.horizontalHeader().setSectionResizeMode(
QHeaderView.ResizeToContents)
# get the current sizePolicy and set it to Maximum, meaning that it will
# use its sizeHint as "maximum": it can expand, but there's no need for
# that, so if any other sibling widget requires more space, it can use it
policy = self.button_table.sizePolicy()
policy.setHorizontalPolicy(policy.Maximum)
# apply the changed policy
self.button_table.setSizePolicy(policy)
self.layer_add = QPushButton("Add layer", self)
self.plotter = QPushButton("plot transmission", self)
# I restored the following lines, which were missing in your edit
self.button_table.setCellWidget(0, 0, self.layer_add)
self.button_table.setCellWidget(1, 0, self.plotter)
self.layer_table = QTableWidget(self)
self.graphWidget = pg.PlotWidget(self)
self.grid = QGridLayout()
self.grid.setSpacing(10)
self.grid.addWidget(self.button_table, 0, 0, 1, 1)
self.grid.addWidget(self.layer_table, 0, 1, 1, 1)
self.grid.addWidget(self.graphWidget, 1, 0, 1, 2)
self.centralWidget().setLayout(self.grid)
As you can see, now the left table only uses the minimum required width, based on the horizontal header width (plus the vertical header width), which in turn is based on the sum of the maximum width of each column.
