python - 如何创建 Drawer 实例并将其附加到 MainWindow
问题描述
我正在努力为我的应用程序添加侧边菜单。
我有一个QMainWindow
实例,我希望向其中添加一个QDrawer
对象并实现与此示例类似的效果。
不幸的是,似乎PySide2
只提供了QMenu
,QTooltip
和从类QDialog
继承的小部件,并且无处可寻。但是,在 QML 文件中使用标签就可以了。难道不应该也可以以编程方式创建一个实例吗?Popup
QDrawer
Drawer
QDrawer
作为另一次尝试,我尝试Drawer
从 QML 文件加载一个实例并将其附加到我的QMainWindow
. 不幸的是,我不太明白我应该指定什么作为父级,我应该将它包装在什么中,我应该使用什么参数等 - 任何建议都将不胜感激(尽管我更愿意以编程方式创建和配置它)。
我的目标是创建一个QMainWindow
带有工具栏、中央小部件和一个QDrawer
实例的侧导航菜单(例如在这个示例中)。您能否分享一些示例或解释该怎么做?
解决方案
一种可能的解决方案是使用 Qt Widgets 实现 Drawer,主要功能是动画宽度的变化,例如使用 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_())
推荐阅读
- checkbox - 加载页面时选中 Kendo Dropdowntree 中的所有复选框
- reactjs - React + Material-UI + Typescript:从按钮继承道具以添加不同的变体
- jquery - jQuery:如何获取文本并设置为属性?
- asp.net - 在视图中显示一对多属性
- php - 更新 .htaccess 以减少 URL 的长度
- swift - 此代码是否会增加引用计数?
- powershell - 未找到 VSCode、Powershell、cmdlet (Netlify) 'netlify init'
- c# - 在 Visual Studio 中编写的 Azure 队列触发函数未侦听队列
- ios - 取消粗体通知权限 UI 警报操作文本
- python - 如何逐渐将当前的 Django 单元测试转移到 pytest?