Как создать экземпляр Drawer и прикрепить его к MainWindow - PullRequest
0 голосов
/ 07 февраля 2020

Я изо всех сил пытаюсь добавить боковое меню в свое приложение.

У меня есть экземпляр QMainWindow, к которому я надеялся добавить объект QDrawer и добиться эффекта, аналогичного this sample .

К сожалению, похоже, что PySide2 предоставляет только виджеты QMenu, QTooltip и QDialog, которые наследуются от класса Popup и QDrawer нигде не найти. Однако использование тега Drawer в файле QML работает просто отлично. Разве не возможно также создать экземпляр QDrawer программно?

В качестве еще одной попытки я попытался загрузить экземпляр Drawer из файла QML и прикрепить его к моему QMainWindow. К сожалению, я не совсем понимаю, что мне следует указывать в качестве родительского, во что оборачивать, какие параметры использовать et et 1030 *. - любой совет был бы оценен (хотя я бы предпочел создать и настроить его программно).

Моя цель - создать QMainWindow с панелью инструментов, центральным виджетом и экземпляром QDrawer в качестве боковой навигации. меню (например, это образец). Можете ли вы поделиться некоторыми примерами или объяснить, что делать?

1 Ответ

1 голос
/ 07 февраля 2020

Одним из возможных решений является реализация Drawer с использованием виджетов Qt, основная функция - анимация изменения ширины, например, с помощью QXAnimation, другая задача - установить привязки так, чтобы они занимали необходимую высоту. Простой пример показан в следующем коде:

import os

from PySide2 import QtCore, QtGui, QtWidgets


class Drawer(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setFixedWidth(0)
        self.setContentsMargins(0, 0, 0, 0)
        # self.setFixedWidth(0)
        self._maximum_width = 0

        self._animation = QtCore.QPropertyAnimation(self, b"width")
        self._animation.setStartValue(0)
        self._animation.setDuration(1000)
        self._animation.valueChanged.connect(self.setFixedWidth)
        self.hide()

    @property
    def maximum_width(self):
        return self._maximum_width

    @maximum_width.setter
    def maximum_width(self, w):
        self._maximum_width = w
        self._animation.setEndValue(self.maximum_width)

    def open(self):
        self._animation.setDirection(QtCore.QAbstractAnimation.Forward)
        self._animation.start()
        self.show()

    def close(self):
        self._animation.setDirection(QtCore.QAbstractAnimation.Backward)
        self._animation.start()


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)

        self.tool_button = QtWidgets.QToolButton(
            checkable=True, iconSize=QtCore.QSize(36, 36)
        )

        content_widget = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
        content_widget.setText("Content")
        content_widget.setStyleSheet("background-color: green")

        lay = QtWidgets.QVBoxLayout(central_widget)
        lay.setSpacing(0)
        lay.setContentsMargins(0, 0, 0, 0)
        lay.addWidget(self.tool_button)
        lay.addWidget(content_widget)

        self.resize(640, 480)

        self.drawer = Drawer(self)
        self.drawer.move(0, self.tool_button.sizeHint().height())
        self.drawer.maximum_width = 200
        self.drawer.raise_()

        content_lay = QtWidgets.QVBoxLayout()
        content_lay.setContentsMargins(0, 0, 0, 0)
        label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
        label.setText("Content\nDrawer")
        label.setStyleSheet("background-color: red")
        content_lay.addWidget(label)
        self.drawer.setLayout(content_lay)

        self.tool_button.toggled.connect(self.onToggled)

        self.onToggled(self.tool_button.isChecked())

        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.onCustomContextMenuRequested)

    @QtCore.Slot()
    def onCustomContextMenuRequested(self):
        menu = QtWidgets.QMenu()
        quit_action = menu.addAction(self.tr("Close"))
        action = menu.exec_(QtGui.QCursor.pos())
        if action == quit_action:
            self.close()

    @QtCore.Slot(bool)
    def onToggled(self, checked):
        if checked:
            self.tool_button.setIcon(
                self.style().standardIcon(QtWidgets.QStyle.SP_MediaStop)
            )
            self.drawer.open()
        else:
            self.tool_button.setIcon(
                self.style().standardIcon(QtWidgets.QStyle.SP_MediaPlay)
            )
            self.drawer.close()

    def resizeEvent(self, event):
        self.drawer.setFixedHeight(self.height() - self.drawer.pos().y())
        super().resizeEvent(event)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
...