La adición o eliminación de un QWidget sin afectar a ningún otro de los widgets

0

Pregunta

Tengo un PyQT aplicación con una barra de herramientas, un conjunto de botones, y una fila inferior de botones adicionales. Me gustaría añadir un editor de texto debajo de la fila inferior que el usuario puede ocultar o mostrar. Me gustaría que el TextEdit para extender la parte inferior cuando se muestra, pero, cuando el usuario se esconde, me gustaría que la parte inferior quitar sin afectar la altura, anchura o tamaño de cualquier otro de los botones. Imagino que sólo toma un par de tijeras para el TextEdit sección cuando el usuario lo oculta, pero, a continuación, pegar la espalda cuando el usuario lo quiere de vuelta. Esto es incluso posible hacer en PyQt? Lo más cercano que he encontrado es la aplicación por debajo de la cual cambia el tamaño de todos los botones.

from PyQt5.QtCore import Qt, QPoint, QTimer, QThread, QSize
from PyQt5.QtGui import QFont, QImage, QPainter, QPen, QPixmap
from PyQt5.QtWidgets import (
    QAction, QApplication, QCheckBox, QFileDialog, QHBoxLayout, QLabel,
    QMainWindow, QMenu, QMenuBar, QPlainTextEdit, QPushButton, QSpacerItem,
    QSizePolicy, QFrame,
    QTextEdit, QVBoxLayout, QWidget, QGridLayout, QToolButton, QComboBox
)
from PyQt5.QtWidgets import QApplication
import sys


class AppWindow(QMainWindow):
    def __init__(self, main_widget):
        super(AppWindow, self).__init__()
        self.main_widget = main_widget
        self.setCentralWidget(self.main_widget)


class AppWidget(QWidget):
    def __init__(self, panels=[]):
        super(AppWidget, self).__init__()
        self.panels = panels
        self.main_layout = QVBoxLayout(self)

        self.setSizePolicy(
            QSizePolicy.MinimumExpanding,
            QSizePolicy.MinimumExpanding
        )

        self.toolbar_frame = QFrame(self)
        self.toolbar_frame_layout = QHBoxLayout(self.toolbar_frame)
        self.toolbar_frame_layout.addStretch()
        self.log_button = QToolButton(self.toolbar_frame)
        self.log_button.setText('Toggle Log')

        self.toolbar_frame_layout.addWidget(self.log_button)
        self.toolbar_frame.setLayout(self.toolbar_frame_layout)

        self.project_frame = QFrame(self)

        self.project_frame_layout = QHBoxLayout(self.project_frame)
        self.project_dropdown = QComboBox(self.project_frame)
        self.project_dropdown.setMinimumSize(20, 0)
        self.project_refresh = QToolButton(self.project_frame)
        self.project_refresh.setText('Refresh')
        self.project_frame_layout.addWidget(self.project_dropdown)
        self.project_frame_layout.addWidget(self.project_refresh)
        self.project_frame.setLayout(self.project_frame_layout)

        self.panel_frame = QFrame(self)
        self.panel_frame_layout = QVBoxLayout(self.panel_frame)
        for panel in panels:
            self.panel_frame_layout.addWidget(panel)
        self.panel_frame.setLayout(self.panel_frame_layout)

        self.bottom_frame = QFrame(self)
        self.bottom_frame_layout = QHBoxLayout(self.bottom_frame)
        self.bottom_frame_layout.addStretch()
        self.sg_button = QToolButton()
        self.sg_button.setText('Extra Stuff')
        self.bottom_frame_layout.addWidget(self.sg_button)
        self.bottom_frame.setLayout(self.bottom_frame_layout)

        self.log = QTextEdit()
        self.log_frame = QFrame(self)
        self.log_frame_layout = QHBoxLayout(self.log_frame)
        self.log_frame_layout.addWidget(self.log)
        self.log_frame.setLayout(self.log_frame_layout)

        self.main_layout.addWidget(self.toolbar_frame)
        self.main_layout.addWidget(self.project_frame)
        self.main_layout.addWidget(self.panel_frame)
        self.main_layout.addWidget(self.bottom_frame)
        self.app_widgets = QWidget(self)
        self.app_widgets.setLayout(self.main_layout)
        self.log_widget = QWidget(self)
        self.log_widget.setLayout(self.log_frame_layout)

        self.total_layout = QVBoxLayout(self)
        self.total_layout.addWidget(self.app_widgets)
        self.total_layout.addWidget(self.log_widget)

        self.setLayout(self.total_layout)

        self.log_button.clicked.connect(self.toggle_log)

    def toggle_log(self):
        if self.log_widget.isHidden():
            self.log_widget.show()
            QTimer.singleShot(0, self.resize_show)
        else:
            self.log_widget.hide()
            QTimer.singleShot(0, self.resize_hide)
        # self.adjustSize() Also does not work.
    def resize_show(self):
        self.resize(self.width(), self.sizeHint().height())

    def resize_hide(self):
        self.resize(self.width(), self.minimumSizeHint().height())


class AppPanel(QWidget):
    def __init__(self, sections=[]):
        super(AppPanel, self).__init__()
        self.setSizePolicy(
            QSizePolicy.MinimumExpanding,
            QSizePolicy.MinimumExpanding
        )
        self.layout = QVBoxLayout(self)
        self.setLayout(self.layout)
        self.sections = sections
        for section in self.sections:
            self.layout.addWidget(section)


class AppSection(QWidget):
    def __init__(self, buttons=[]):
        super(AppSection, self).__init__()
        self.setSizePolicy(
            QSizePolicy.MinimumExpanding,
            QSizePolicy.MinimumExpanding
        )
        self.buttons = buttons
        self.layout = QGridLayout()
        for i, button in enumerate(self.buttons):
            col = i % 2
            row = i // 2
            self.layout.addWidget(button, row, col)
        self.setLayout(self.layout)


class AppButton(QToolButton):
    def __init__(self, text=''):
        super(AppButton, self).__init__()
        self.setText(text)
        self.setFocusPolicy(Qt.NoFocus)
        self.setIconSize(QSize(50, 50))
        self.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app_buttons = [AppButton(text='APPS ' + str(i)) for i in range(5)]
    custom_btns = [AppButton(text='Custom ' + str(i)) for i in range(5)]
    app_section = AppSection(buttons=app_buttons)
    custom_section = AppSection(buttons=custom_btns)
    panels = [AppPanel(sections=[app_section, custom_section])]
    ex = AppWidget(panels=panels)
    lw = AppWindow(main_widget=ex)
    lw.show()
    app.exec_()
pyqt pyqt5 python
2021-11-23 02:11:29
2

Mejor respuesta

0

Cambiar el tamaño del widget por sí sola no es una solución válida, ya que sólo anula la geometría establecida por el diseño, sin necesidad de notificar a los padres widget.

Esto también es importante, ya que no debe cambiar el tamaño del widget basado en su pista solo cuando se muestra el registro: si se aumenta el tamaño de la ventana mientras que el registro está oculto y, a continuación, se mostrará de nuevo, no va a ocupar todo el espacio disponible.

Lo que usted necesita hacer es acceder a la ventana de nivel superior, la fuerza de su diseño para diseñar su contenido de nuevo, y el uso de su sugerencia para el cambio de tamaño.

    def resize_hide(self):
        self.window().layout().activate()
        self.window().resize(
            self.window().width(), 
            self.window().minimumSizeHint().height()
        )
2021-11-23 11:10:30
0

Puede establecer la alineación de la política de su parte superior del widget:

[...]
self.total_layout.setAlignment(self.app_widgets, Qt.AlignTop)

self.setLayout(self.total_layout)
[...]

El app_widget no cambiará de tamaño más al ocultar su edición de texto.

2021-11-23 08:53:16

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................