Vince
Vince

Reputation: 4401

python qt : automatically resizing main window to fit content

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.

Upvotes: 10

Views: 51789

Answers (5)

user1098761
user1098761

Reputation: 579

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.

Upvotes: 0

Mubarak Yahaya
Mubarak Yahaya

Reputation: 23

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_()) 

Upvotes: 0

Kamiyab Taqizadeh
Kamiyab Taqizadeh

Reputation: 21

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());

Upvotes: 1

stephenprocter
stephenprocter

Reputation: 31

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_())

Upvotes: 1

Daniele Pantaleone
Daniele Pantaleone

Reputation: 2723

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.

Upvotes: 3

Related Questions