Başka widget'ları etkilemeden QWidget ekleme veya kaldırma

0

Soru

Bir araç çubuğu, bir dizi düğme ve bir alt sıra ek düğme içeren bir PyQT uygulamam var. Kullanıcının gizleyebileceği veya gösterebileceği alt satırın altına bir TextEdit eklemek istiyorum. Textedit'in gösterildiğinde alt kısmı genişletmesini istiyorum, ancak kullanıcı gizlediğinde, düğmelerin herhangi birinin yüksekliğini, genişliğini veya boyutunu etkilemeden alt kısmın kaldırılmasını istiyorum. Kullanıcı gizlediğinde TextEdit bölümüne sadece bir makas aldığınızı, ancak kullanıcı geri istediğinde tekrar yapıştırdığınızı düşünün. Pyqt'de bunu yapmak mümkün mü? Bulduğum en yakın şey, tüm düğmeleri yeniden boyutlandıran aşağıdaki uygulamadır.

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

En iyi cevabı

0

Widget'ı tek başına yeniden boyutlandırmak geçerli bir çözüm değildir, çünkü yalnızca üst widget'ı bildirmeden mizanpaj tarafından ayarlanan geometriyi geçersiz kılar.

Bu, günlüğü gösterirken widget'ı yalnızca ipucuna göre yeniden boyutlandırmamanız gerektiğinden de önemlidir: günlük gizlenirken pencerenin boyutunu artırıp tekrar gösterirseniz, kullanılabilir tüm alanı kaplamaz.

Yapmanız gereken en üst düzey pencereye erişmek, düzenini içeriğini yeniden yerleştirmeye zorlamak ve yeniden boyutlandırmak için ipucunu kullanmaktır.

    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

Üst widget'ınız için hizalama ilkesini ayarlayabilirsiniz:

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

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

Bu app_widget metin düzenlemenizi gizlediğinizde artık yeniden boyutlandırılmayacaktır.

2021-11-23 08:53:16

Diğer dillerde

Bu sayfa diğer dillerde

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