Closed rainzee closed 1 year ago
重写委托应该就行了,qt 也有提供过滤 item 的类
那为什么Groove选择手动移除所有卡片,然后再排序等等,而不是使用委托来进行。这里有什么取舍吗?
groove的卡片交互行为比较复杂,委托不太好写
像是 AlbumCard 上还有按钮,估计委托做不到这一点
我的卡片上面也有按钮,但是和Groove比起来很简单,只有一个简单地PushButton,但是我希望能够想Fluent-Widget里的Icon-Interface一样,用Flowlayout来布局,这样可以做到吗?
理论上你可以画一个按钮出来
简单来说,我希望能够进行搜索,筛选,排序,然后在卡片上有按钮和控件,在您看来,最合适的方案是什么
但是我觉得会很麻烦,得判断鼠标点击位置以及绘制不同状态下按钮的样式,不如直接 setIndexWidgets 来的方便
让我来写的话肯定还是写一个自定义组件,然后用 QListWidget.setIndexWidget
虽然速度慢一些,但是好写
实际上分页查询应该也不会很慢,不需要创建新的卡片,只要更新既有的卡片就行
但是您Groove和Icon里都是用的ScroolArea,然后手动控制移除,这是出于什么考虑呢?
def search(self, keyWord: str):
""" search icons """
items = self.trie.items(keyWord.lower())
indexes = {i[1] for i in items}
self.flowLayout.removeAllWidgets()
for i, card in enumerate(self.cards):
isVisible = i in indexes
card.setVisible(isVisible)
if isVisible:
self.flowLayout.addWidget(card)
上面是您在Icon中的实现,用前缀树和setVisable来手动实现搜索。
def sortByAddTime(self):
""" sort album cards by added time """
self.sortMode = "Date added"
self.__removeViewFromLayout()
self.__createAlbumCardView(self.albumCards)
self.__addViewToLayout()
def sortByFirstLetter(self):
""" sort album cards by first letter """
self.sortMode = "A to Z"
self.__removeViewFromLayout()
firstLetters = {} # type:Dict[str, List[AlbumCard]]
for card in self.albumCards:
letter = pinyin.get_initial(card.album[0])[0].upper()
letter = letter if 65 <= ord(letter) <= 90 else "..."
if letter not in firstLetters:
firstLetters[letter] = []
firstLetters[letter].append(card)
# sort group
groupCards = sorted(firstLetters.items(), key=lambda i: i[0])
# remove ... group to the last position
if "..." in firstLetters:
groupCards.append(groupCards.pop(0))
# create views
for letter, cards in groupCards:
view = self.__createAlbumCardView(cards, letter)
view.titleClicked.connect(
lambda: signalBus.switchToLabelNavigationInterfaceSig.emit(list(firstLetters.keys()), "grid"))
self.__addViewToLayout()
def sortByYear(self):
""" sort album cards by release year """
self.sortMode = "Release year"
self.__removeViewFromLayout()
years = {} # type:Dict[str, List[AlbumCard]]
for card in self.albumCards:
year = card.year if card.year else self.tr('Unknown')
if year not in years:
years[year] = []
years[year].append(card)
# sort groups by year
groupCards = sorted(years.items(), key=lambda i: i[0], reverse=True)
years = sorted(years.keys(), reverse=True)
if self.tr("Unknown") in years:
groupCards.append(groupCards.pop(0))
# create views
for year, cards in groupCards:
view = self.__createAlbumCardView(cards, year)
view.titleClicked.connect(
lambda: signalBus.switchToLabelNavigationInterfaceSig.emit(years, "list"))
self.__addViewToLayout()
def sortBySinger(self):
""" sort album cards by singer """
self.sortMode = "Artist"
self.__removeViewFromLayout()
singers = {} # type:Dict[str, List[AlbumCard]]
for card in self.albumCards:
singer = card.singer
if singer not in singers:
singers[singer] = []
singers[singer].append(card)
# sort groups
groupCards = sorted(
singers.items(), key=lambda i: pinyin.get_initial(i[0])[0].lower())
# create views
for singer, cards in groupCards:
view = self.__createAlbumCardView(cards, singer)
view.titleClicked.connect(
lambda: signalBus.switchToLabelNavigationInterfaceSig.emit(list(singers.keys()), "grid"))
self.__addViewToLayout()
下面是Groove中的相关实现,直接移除所有控件,我不清楚这在很多歌曲时候的表现,您这么写当时是有什么考量吗?
速度挺快的,因为没有创建新的卡片,只是改了一下位置
当初这么写是因为希望能够自己掌控界面布局,不受到 QListWidget 的影响
QListWidget中能够完全自己布局吗,不是一条表格,而是类似于IconInterface中的FlowLayout
IconInterface 没用 QListWidget 的原因是我忘了可以这么写🥲
QListWidget 改一下视图模式就行,日历组件就是 QListWidget
非常感谢您的快速回复,稍后会在爱发电支持。还有困惑的地方再请教您。
😄小问题
I want to implement a searchable, filterable, sortable view that displays custom widgets, such as cards, QTableView and QStyledItemDelegate in Qt are the most relevant widgets I can find, but it can only display tables, the relevant implementation in Groove is to use StackedWidget and manually control the removal of all widgets. Is there a more elegant way to do this? Because I will have a lot of widgets, probably thousands, and I want to be able to work with both paging and streaming loading.
I hope you can provide some ideas, or keywords, I really have no ideas. Or simply tell me if Model-View in Qt is a dead end.