Adăugarea sau eliminarea unui QWidget fără a afecta orice alte widget-uri

0

Problema

Am o PyQT aplicație cu o bară de instrumente, un set de butoane, și un rând de jos de butoane suplimentare. Aș vrea să adaug un TextEdit sub rândul de jos care utilizatorul poate ascunde sau afișa. Mi-ar place TextEdit pentru a extinde partea de jos atunci când sunt afișate, dar, atunci când utilizatorul se ascunde, mi-ar plăcea parte de jos înlăturate fără a afecta înălțimea, lățimea, sau dimensionarea orice alte butoane. Imaginați-vă doar de a lua o pereche de foarfece pentru TextEdit secțiune atunci când utilizatorul se ascunde, dar apoi lipire înapoi pe atunci când utilizatorul vrea înapoi. Acest lucru este chiar posibil să se facă în PyQt? Cel mai aproape am gasit este punerea în aplicare de mai jos, care redimensionează toate butoanele.

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

Cel mai bun răspuns

0

Redimensionarea widget-ul în sine nu este o soluție validă, deoarece nu numai că anulează geometria set de aspect fără a notifica părinte widget.

Acest lucru este, de asemenea, important ca tu nu ar trebui să redimensiona widget pe baza indiciu singur atunci când arată jurnal: dacă crește dimensiunea ferestrei în timp ce jurnalul este ascuns și apoi să-l arate din nou, acesta nu va ocupa tot spațiul disponibil.

Ceea ce trebuie să faceți este de a avea acces la nivelul de sus a ferestrei, forța aspectul său pentru a-și expune din nou conținutul, și de a folosi indicii pentru a pentru a redimensiona.

    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

Puteți seta alinierea politicii pentru widget-ul de top:

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

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

La app_widget nu va fi redimensionate atunci când te ascunzi de editare a textului.

2021-11-23 08:53:16

În alte limbi

Această pagină este în alte limbi

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