1

not so many experience at all with pyqt..

I have designed an UI with Qt Designer with 2 Radiobuttons.

Depending on the RadioButton selected some widgets are visible and other not. What I'm not trying to do is to resize automatically the layout of the dialog depending on how many widgets are visible in the UI.

The question is very similar to this one . Here the extract of the code that might be helpful to understand the problem (I know it is just a piece of the code, but the entire dialog is pretty long):

class MyDialog(QDialog, FORM_CLASS):
    ..........

    # connect the radioButton with a function that reloads the UI
    self.radioSingle.toggled.connect(self.refreshWidgets)


    .....

    # dictionary with all the widgets and the values
    self.widgetType = {
            self.cmbModelName: ['all'],
            self.cmbGridLayer: ['all'],
            self.cmbRiverLayer: ['all'],
            self.lineNewLayerEdit: ['all'],
            self.lineLayerNumber: ['single']
        }

# function that refresh the UI with the correct widgets depending on the radiobutton selected
    def refreshWidgets(self, idx):
        '''
        refresh UI widgets depending on the radiobutton chosen
        '''


        tp = self.radioSingle.isChecked()

        for k, v in self.widgetType.items():
            if tp:
                if 'all' or 'single' in v:
                    active = True
                k.setEnabled(active)
                k.setVisible(active)
            else:
                active = 'all' in v
                k.setEnabled(active)
                k.setVisible(active)

        # attempt to resize the Dialog
        self.setSizeConstraint()

Surely the code could be improved (not so skilled with code writing)...

Community
  • 1
  • 1
matteo
  • 4,683
  • 9
  • 41
  • 77

1 Answers1

0

You just gotta set_up your UI to resize when it's needed. There is a lot of more beautiful way to do this, but here is a simple and fast example:

You just have to define your layout to behave the way you want. If you make use of Minimum and Maximum size it'll resize as you need. You could also have your own personalized buttons, widgets, .... you would have a cleaner code.

import sys

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QDialog
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QRadioButton
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QWidget


class CustomDialog(QDialog):

    w_container = None
    v_layout_container = None
    v_scroll_area = None
    v_layout_preview = None


    def __init__(self):
        """Init UI."""

        super(CustomDialog, self).__init__()
        self.init_ui()

    def init_ui(self):
        """Init all ui object requirements."""

        self.r1 = QRadioButton("smaller")
        self.r2 = QRadioButton("bigger")

        style = "background: green;"
        size = [200, 50]

        self.small_size = [200, 250]
        self.big_size = [200, 500]

        self.resize(200,200)

        self.w1 = QWidget()
        self.w2 = QWidget()
        self.w3 = QWidget()
        self.w4 = QWidget()
        self.w5 = QWidget()
        self.w6 = QWidget()
        self.w1.setStyleSheet(style)
        self.w2.setStyleSheet(style)
        self.w3.setStyleSheet(style)
        self.w4.setStyleSheet(style)
        self.w5.setStyleSheet(style)
        self.w6.setStyleSheet(style)
        self.w1.setFixedSize(size[0], size[1])
        self.w2.setFixedSize(size[0], size[1])
        self.w3.setFixedSize(size[0], size[1])
        self.w4.setFixedSize(size[0], size[1])
        self.w5.setFixedSize(size[0], size[1])
        self.w6.setFixedSize(size[0], size[1])

        self.full_container = QVBoxLayout()
        self.full_container.setContentsMargins(0,0,0,0)

        self.radio_widget = QWidget()
        self.radio_widget.setFixedSize(200, 50)
        self.radio_container = QHBoxLayout()
        self.radio_container.setContentsMargins(0,0,0,0)

        self.widget_widget = QWidget()
        self.widget_container = QVBoxLayout()

        self.radio_widget.setLayout(self.radio_container)
        self.widget_widget.setLayout(self.widget_container)

        self.full_container.addWidget(self.radio_widget)
        self.full_container.addWidget(self.widget_widget)

        self.radio_container.addWidget(self.r1)
        self.radio_container.addWidget(self.r2)

        self.widget_container.addWidget(self.w1)
        self.widget_container.addWidget(self.w2)
        self.widget_container.addWidget(self.w3)
        self.widget_container.addWidget(self.w4)
        self.widget_container.addWidget(self.w5)
        self.widget_container.addWidget(self.w6)

        self.setLayout(self.full_container)

        self.r1.setChecked(True)

    def paintEvent(self, event):
        if self.r1.isChecked():
            self.w4.hide()
            self.w5.hide()
            self.w6.hide()
            self.setFixedSize(self.small_size[0],self.small_size[1])
        elif self.r2.isChecked():
            self.w4.show()
            self.w5.show()
            self.w6.show()
            self.setFixedSize(self.big_size[0], self.big_size[1])
        self.full_container.update()
        super(CustomDialog, self).paintEvent(event)

def run():
    app = QApplication(sys.argv)
    GUI = CustomDialog()
    GUI.show()
    sys.exit(app.exec_())


run()

Observe that I'm using PyQt5, so if you need you just gotta change your imports to the version you are using.

yurisnm
  • 1,630
  • 13
  • 29
  • See also that I'm using the paintEvent to keep veryfing if it changes or not, since the paintEvent is in the main thread it's in constant execution. Better way to do this is to have your own customized radio buttons and override the "changed" method of it. If it changed you'd resize your Dialog. Something like that ^^ – yurisnm Nov 10 '16 at 14:22
  • Hi.. thanks for the answer, very complete.. However, if I've understand correctly, you suggest to set the Dialog size "by hand" right? I was looking for a method that knows the new dimension of the layout when some widget are not visible anymore.. – matteo Nov 10 '16 at 18:57
  • Yeah, you are correct, just get my code and make it run. Take out the setFixedSize. If you manually resize it to a small size, when u mark the big radio it'll still grow, and small will still decrease. The way I did was just one of many examples. ") – yurisnm Nov 10 '16 at 19:01
  • Even though it's with not .setFixedSize() it'll still grow and decrease by itself :p – yurisnm Nov 10 '16 at 19:12