9

I have a main window which contains a main widget, to which a vertical layout is set. To the layout is added a QTableWidget only (for the moment).

When I start the application and call show on the main_window, only part of the QTableWidget is shown. I can extend the window manually to see it all, but I would like the window to have its size nicely adapted to the size of the QTableWidget.

Googling the question found a lot of posts on how to use resize to an arbitrary size, and call to resize(int) works fine, but this is not quite what I am asking

Lots of other posts are not explicit enough, e.g "use sizePolicy" or "use frameGeometry" or "use geometry" or "use sizeHint". I am sure all of them may be right, but an example on how to would be awesome.

AAEM
  • 1,837
  • 2
  • 18
  • 26
Vince
  • 3,979
  • 10
  • 41
  • 69
  • 1
    I'm willing to bet that there's something wrong in the way you set up your layouts/widgets. In a properly layouted scenario, your main window would never shrink smaller than the enclosed tablewidgets minimum-size. You'll need to provide some code example. – ThorngardSO Jan 07 '16 at 12:46

5 Answers5

5

You can do something like this, from within your MainWindow after placing all the elements you need in the layout:

self.setFixedSize(self.layout.sizeHint())

This will set the size of the MainWindow to the size of the layout, which is calculated using the size of widgets that are arranged in the layout.

Daniele Pantaleone
  • 2,657
  • 22
  • 33
  • Hi, does not seem to work ... I tried sizeHint on different object, and what it returns does not seem to match anything --; – Vince Jan 07 '16 at 11:09
  • `AttributeError: 'builtin_function_or_method' object has no attribute 'sizeHint'`, though it worked using the central widget. The big issue here is the window becomes fixed in size, and using table.sizeHint made it too small. – rtaft Feb 24 '23 at 14:59
  • doesn't work... – Stéphane Aug 14 '23 at 13:14
2

I think overriding sizeHint() on the QTableWidget is the key:

import sys
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidget

class Table(QTableWidget):
  def sizeHint(self):
    horizontal = self.horizontalHeader()
    vertical = self.verticalHeader()
    frame = self.frameWidth() * 2
    return QSize(horizontal.length() + vertical.width() + frame,
                 vertical.length() + horizontal.height() + frame)

class Main(QMainWindow):
  def __init__(self, parent=None):
    super(Main, self).__init__(parent)
    top = Table(3, 5, self)
    self.setCentralWidget(top)

if __name__ == '__main__':
  app = QApplication(sys.argv)
  main = Main()
  main.show()
  sys.exit(app.exec_())
  • 1
    It might be a good idea to use `vertical.sizeHint().width()` instead of `vertical.width()` and `horizontal.sizeHint().height()` instead of `horizontal.height()`. See https://stackoverflow.com/a/69035062/2705757 . – AXO Sep 02 '21 at 18:32
0

You can use sizeHint() but not as stated in the other answers. sizeHint() returns a QSize object with a width and height. Let's say you have a main window mainWindow and a widget inside it called content. If your resizing involves content height to get bigger, you can fit the mainWindow to it like this:

mainWindow.resize(mainWindow.sizeHint().width,
        mainWindow.size().height() + content.sizeHint().height());
AAEM
  • 1,837
  • 2
  • 18
  • 26
0

Old but i experienced this a while back and seeing how the answers here didn't exactly work for me.

Here's what i did:

Please make sure you have the central widget for the 'mainwindow' set properly and the parent of the layout is the central widget, Then set a sizepolicy for the mainwindow/widget as you wish.


from PyQt5 import QtCore, QtGui, QtWidgets
import sys

class RandomWidget(QtWidgets.QWidget):

    def __init__(self, parent=None):
        super(RandomWidget, self).__init__(parent)
        self.layout = QtWidgets.QVBoxLayout()
        self.setLayout(self.layout)
        self.ui()
        self.layout.addWidget(self.table)
        self.layout.addWidget(self.table2)

    def ui(self):
        self.table = QtWidgets.QTableWidget()
        self.table.setMinimumSize(800,200)
        self.table2 = QtWidgets.QTableWidget()

class Mainwindow(QtWidgets.QMainWindow):

    def __init__(self):
        self.widget = None
        super(Mainwindow, self).__init__()
        self.setWindowTitle('test')

    def ui(self):
        self.setCentralWidget(self.widget)
        self.show()
    

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    Window = Mainwindow()
    Window.widget = RandomWidget(Window)
    Window.ui()
    sys.exit(app.exec_()) 

  • 1
    Thank - but I don't see "set a sizepolicy" anywhere in the code example? Only setMinimumSize? – sdbbs Jan 27 '21 at 09:38
0

When you create a main class, set the width of height of some widget to change according to the main window.

def _setupUi(self):
    self.original_width = 1280
    self.original_height = 773
    self.file_list_w = 256
    self.file_list_h = 350
    self.file_list.setGeometry(QRect(30, 20, self.file_list_w, self.file_list_h))

and in the main class, add this

def resizeEvent(self, event):
    width = self.frameGeometry().width()
    height = self.frameGeometry().height()
    w_proportion = width / self.original_width
    h_proportion = height / self.original_height
    self.file_list.resize(int(self.file_list_w*w_proportion), int(self.file_list_h*h_proportion))

And do the same thing for any widget needs to be adjusted when the main windows is resizing.

user1098761
  • 579
  • 1
  • 5
  • 16