Изменить размер QDialog, когда RadioButton отмечен PyQt

не так много опыта вообще с pyqt..

Я разработал пользовательский интерфейс с помощью Qt Designer с двумя радиокнопками.

В зависимости от выбранного RadioButton некоторые виджеты видны, а другие нет. Чего я не пытаюсь сделать, так это автоматически изменить размер макета диалогового окна в зависимости от того, сколько виджетов отображается в пользовательском интерфейсе.

Вопрос очень похож на этот вопрос . Вот отрывок кода, который может быть полезен для понимания проблемы (я знаю, что это всего лишь часть кода, но весь диалог довольно длинный):

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

Конечно, код можно было бы улучшить (не настолько опытный в написании кода)...


person matteo    schedule 10.11.2016    source источник


Ответы (1)


Вы просто должны настроить свой пользовательский интерфейс, чтобы изменить размер, когда это необходимо. Есть много более красивых способов сделать это, но вот простой и быстрый пример:

Вам просто нужно определить свой макет, чтобы он вел себя так, как вы хотите. Если вы используете минимальный и максимальный размер, он будет изменяться по мере необходимости. Вы также могли бы иметь свои собственные персонализированные кнопки, виджеты, ... у вас был бы более чистый код.

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

Обратите внимание, что я использую PyQt5, поэтому, если вам нужно, вам просто нужно изменить импорт на версию, которую вы используете.

person yurisnm    schedule 10.11.2016
comment
См. Также, что я использую paintEvent, чтобы следить за тем, изменяется оно или нет, поскольку paintEvent находится в основном потоке и постоянно выполняется. Лучший способ сделать это — иметь свои собственные настраиваемые переключатели и переопределить измененный метод. Если бы он изменился, вы бы изменили размер своего диалога. Как-то так ^^ - person yurisnm; 10.11.2016
comment
Привет .. спасибо за ответ, очень полный .. Однако, если я правильно понял, вы предлагаете установить размер диалога вручную, верно? Я искал метод, который знает новое измерение макета, когда некоторые виджеты больше не видны. - person matteo; 10.11.2016
comment
Да, вы правы, просто возьмите мой код и запустите его. Выньте setFixedSize. Если вы вручную измените его размер до маленького размера, когда вы отметите большое радио, оно все равно будет увеличиваться, а маленькое все равно будет уменьшаться. То, как я это сделал, было лишь одним из многих примеров. ) - person yurisnm; 10.11.2016
comment
Даже если он не .setFixedSize(), он все равно будет расти и уменьшаться сам по себе: p - person yurisnm; 10.11.2016