Dodawanie lub usuwanie QWidget bez wpływu na inne wzory

0

Pytanie

Mam aplikację PyQt z paskiem narzędzi, zestaw przycisków i dolną obok dodatkowych przycisków. Chciałbym dodać wiadomość tekstową pod dolnym ciągiem znaków, które użytkownik może ukryć lub pokazać. Chciałbym, aby TextEdit rozszerzał dolną część po wyświetleniu, ale, gdy użytkownik ukrywa ją, chciałbym, aby ta dolna część została usunięta, nie wpływa na wysokość, szerokość, rozmiar lub dowolnego innego przycisku. Wyobraź sobie, że jesteś po prostu wziąć nożyczki w sekcji TextEdit, gdy użytkownik ukrywa je, ale potem приклеиваете z powrotem, gdy użytkownik chce je odzyskać. Czy jest to możliwe do zrobienia w PyQt? Najbliższe co znalazłem, to realizacja poniżej, która zmienia rozmiar wszystkich przycisków.

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

Najlepsza odpowiedź

0

Zmiana rozmiaru widget samo w sobie nie jest poprawnym rozwiązaniem, ponieważ zastępuje tylko geometrię, określonego układu, bez powiadomienia rodzica widget.

Jest to również ważne, tak jak nie powinny zmienić rozmiar widżetu tylko na podstawie jego wskazówek podczas wyświetlania dziennika: jeśli chcesz zwiększyć rozmiar okna, podczas gdy magazyn jest ukryty, a następnie pokazać go ponownie, nie zajmuje całą dostępną przestrzeń.

Co trzeba zrobić, to uzyskać dostęp do okna najwyższego poziomu, aby jego układ ponownie wyłożyć zawartość i używać go podpowiedź do zmiany rozmiaru.

    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

Można dostosować politykę wyrównywania do swego najwyższego widget:

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

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

To app_widget rozmiar nie zostanie zmieniony, gdy ukrycia edycja tekstu.

2021-11-23 08:53:16

W innych językach

Ta strona jest w innych językach

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