我正在尝试创建一个类似于 Qt Designer 中的可折叠侧面板(参见随附的屏幕截图)。它们似乎是放置在某种可折叠小部件中的 QListView。
我用谷歌搜索“Qt 可折叠面板”,似乎没有标准组件,或者至少没有这个名称。那么,有谁知道任何标准 Qt 组件是否具有相同的行为?如果没有,任何人都可以建议我如何构建它吗?
谢谢。
我正在尝试创建一个类似于 Qt Designer 中的可折叠侧面板(参见随附的屏幕截图)。它们似乎是放置在某种可折叠小部件中的 QListView。
我用谷歌搜索“Qt 可折叠面板”,似乎没有标准组件,或者至少没有这个名称。那么,有谁知道任何标准 Qt 组件是否具有相同的行为?如果没有,任何人都可以建议我如何构建它吗?
谢谢。
我决定遵循 Joey 提供的链接中列出的一般方法。
具体来说,我为每个可折叠列表创建了一个小部件。这个小部件由顶部的 QPushButton 和底部的 QListView 组成。
然后,我将按钮单击信号连接到一个处理程序,以在 QListView 的几何图形在隐藏时的高度为 0 和重新出现时的原始高度之间切换。
我发现与 Claudio 建议的自定义绘制事件相比,这种方法要简单得多。此外,我可以使用 QAnimationProperty 对几何图形的变化进行动画处理,以使列表看起来“滑入”和“滑出”。
但无论如何感谢您的回复!
我创建了可折叠面板。这是代码:
import os
import sys
from pathlib import Path
from PySide2.QtWidgets import QPushButton, QVBoxLayout, QApplication ,QListWidget, QListView, QLabel, QWidget, QAbstractItemView, QSplitter
from PySide2.QtGui import QStandardItemModel, QStandardItem, QIcon, Qt, QDrag
from PySide2 import QtCore
PATH = os.path.join('.','img_src')
print('LayerSelector Loaded with path:' , PATH)
class CustomQStandardItem(QStandardItem):
def __init__(self, icon, text):
super().__init__(icon, text)
def dropMimeData(self, data, action, row, column, parent):
pass
class LayersList(QWidget):
'''
LayerList class which acts as collapsable list.
'''
def __init__(self, name, layers, expand = True):
super().__init__()
self.currently_expanded = True
self.main_layout = QVBoxLayout()
self.main_layout.setMargin(0)
self.main_layout.setSpacing(0)
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.expand_button = QPushButton(name)
self.expand_button.setToolTip(f"List of {name} Layers")
self.expand_button.setIcon(QIcon(os.path.join(PATH,'LayersList_Up.png')))
self.layer_list = QListView()
self.layer_list.setDragEnabled(True)
self.container_model = QStandardItemModel()
for l in layers:
qs = CustomQStandardItem(QIcon(os.path.join(PATH,'LayersList_Layer_Icon.png')),l)
self.container_model.appendRow(qs)
self.layer_list.setModel(self.container_model)
self.layer_list.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.main_layout.addWidget(self.expand_button,0, Qt.AlignTop)
self.main_layout.addWidget(self.layer_list, 0, Qt.AlignTop)
self.expand_button.clicked.connect(self.expand)
self.setLayout(self.main_layout)
self.resized_size = 16.5 * len(layers)
self.set_styling()
if not expand:
self.expand()
@QtCore.Slot()
def expand(self):
if self.currently_expanded:
self.layer_list.setMaximumHeight(0)
self.expand_button.setIcon(QIcon(os.path.join(PATH,'LayersList_Down.png')))
self.currently_expanded = False
else:
self.layer_list.setMaximumHeight(self.resized_size)
self.expand_button.setIcon(QIcon(os.path.join(PATH,'LayersList_Up.png')))
self.currently_expanded = True
def set_styling(self):
self.setStyleSheet("background-color:aliceblue ;")
self.expand_button.setStyleSheet("text-align:left;")
self.layer_list.setStyleSheet("background-color:aliceblue; border:1px solid;border-style: ridge;")
class LayersSelectorWidget(QWidget):
'''
LayerChoiceWidget class provide widget plugin for picking layers.
'''
def __init__(self):
super().__init__()
names = ['Core Layers',
'Convolution Layers',
'Pooling Layers',
'Recurrent Layers',
'Preprocessing Layers',
'Attention Layers',
'Reshaping Layers',
'Locally-Connected Layers'
]
layers = [
['Dense', 'Activation', 'Embedding', 'Masking', 'Lambda'],
['Conv1D', 'Conv2D', 'Conv3D', 'SeparableConv1D', 'SeparableConv2D', 'DepthwiseConv2D', 'Conv2DTranspose', 'Conv3Dtranspose'],
['MaxPooling1D', 'MaxPooling2D', 'MaxPooling3D', 'AveragePooling1D', 'AveragePooling2D', 'AveragePooling3D', 'GlobalMAxPooling1D', 'GlobalMAxPooling2D', 'GlobalMAxPooling3D', 'GlobalAveragePooling1D', 'GlobalAveragePooling2D', 'GlobalAveragePooling3D'],
['LSTM', 'GRU', 'SimpleRNN', 'TimeDistributed', 'BiDirectional', 'ConvLSTM2D'],
['TextToVector', 'Normalization'],
['Attention', 'AdditiveAttention'],
['Reshape', 'Flatten', 'Cropping1D', 'Cropping2D', 'Cropping3D', 'UpSampling1D', 'UpSampling2D', 'UpSampling3D', 'ZeroPadding1D', 'ZeroPadding2D', 'ZeroPadding3D'],
['LocallyConnected1D', 'LocallyConnected2D']
]
self.main_layout = QVBoxLayout()
for i in range(len(names)):
if i > 3:
self.main_layout.addWidget(LayersList(names[i], layers[i], False))
else:
self.main_layout.addWidget(LayersList(names[i], layers[i]))
self.main_layout.setSpacing(0)
self.main_layout.setAlignment(Qt.AlignTop)
self.main_layout.setMargin(0)
self.main_layout.setSpacing(0)
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.main_layout)
del(names)
del(layers)
self.set_styling()
def set_styling(self):
self.setStyleSheet("background-color:aliceblue; border:0px solid;border-style: solid;")
以下是上述代码的结果:
你也可以玩set_styling
来改变外观和感觉。