Skip to content

Commit 790a384

Browse files
committed
更改为qfl的流式布局
1 parent c999569 commit 790a384

2 files changed

Lines changed: 53 additions & 129 deletions

File tree

app/view/another_window/contributor.py

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ def _init_ui(self):
4444
self.main_layout.setContentsMargins(10, 10, 10, 10)
4545
self.main_layout.setSpacing(10)
4646

47-
# 创建网格布局
48-
self.grid_layout = QGridLayout()
49-
self.grid_layout.setSpacing(CONTRIBUTOR_CARD_SPACING)
50-
self.main_layout.addLayout(self.grid_layout)
47+
# 创建流式布局
48+
self.flow_layout = FlowLayout()
49+
self.flow_layout.setVerticalSpacing(CONTRIBUTOR_CARD_SPACING)
50+
self.flow_layout.setHorizontalSpacing(CONTRIBUTOR_CARD_SPACING)
51+
self.main_layout.addLayout(self.flow_layout)
5152

5253
# 初始化卡片列表
5354
self.cards = []
@@ -182,7 +183,7 @@ def create_contributor_cards(self):
182183

183184
# 清空现有卡片列表,但保留在缓存中
184185
self.cards = []
185-
self._clear_grid_layout()
186+
self._clear_flow_layout()
186187

187188
# 添加贡献者卡片
188189
for contributor in self.contributors:
@@ -211,29 +212,19 @@ def create_contributor_cards(self):
211212
# 延迟更新布局
212213
QTimer.singleShot(50, self.update_layout)
213214

214-
def _calculate_columns(self, width: int) -> int:
215-
"""根据窗口宽度和卡片尺寸动态计算列数"""
215+
def _clear_flow_layout(self):
216+
"""清空流式布局"""
217+
# 使用FlowLayout的removeAllWidgets方法清空布局
218+
self.flow_layout.removeAllWidgets()
219+
# 清空已记录的已添加卡片集合
216220
try:
217-
if width <= 0:
218-
return 1
219-
220-
# 计算可用宽度(减去左右边距)
221-
available_width = width - 40 # 左右各20px边距
222-
223-
# 所有卡片使用相同的尺寸
224-
card_actual_width = CONTRIBUTOR_CARD_MIN_WIDTH + CONTRIBUTOR_CARD_SPACING
225-
max_cols = max(1, available_width // card_actual_width)
226-
227-
# 至少显示1列,且不超过最大列数限制
228-
return max(1, min(int(max_cols), CONTRIBUTOR_MAX_COLUMNS))
221+
self._cards_set.clear()
229222
except Exception as e:
230-
from loguru import logger
231-
logger.exception("Error calculating columns (fallback to 1): {}", e)
232-
return 1
223+
logger.exception("Error clearing cards set (ignored): {}", e)
233224

234225
def update_layout(self):
235226
"""更新布局"""
236-
if not self.grid_layout or not self.cards:
227+
if not self.flow_layout or not self.cards:
237228
return
238229

239230
# 检查是否需要更新布局
@@ -269,26 +260,16 @@ def update_layout(self):
269260
self.setUpdatesEnabled(False)
270261

271262
# 清空现有布局
272-
self._clear_grid_layout()
273-
274-
# 计算列数
275-
window_width = max(self.width(), self.sizeHint().width())
276-
columns = self._calculate_columns(window_width)
263+
self._clear_flow_layout()
277264

278-
# 添加卡片到网格布局
279-
for i, card in enumerate(self.cards):
280-
row = i // columns
281-
col = i % columns
265+
# 添加卡片到流式布局
266+
for card in self.cards:
282267
card.setMinimumWidth(CONTRIBUTOR_CARD_MIN_WIDTH)
283268
card.setMaximumWidth(CONTRIBUTOR_CARD_MIN_WIDTH * 1.5)
284-
self.grid_layout.addWidget(card, row, col)
269+
self.flow_layout.addWidget(card)
285270
# 仅在控件当前不可见时显示,避免重复触发绘制
286271
if not card.isVisible():
287272
card.show()
288-
289-
# 设置列的伸缩因子,使卡片均匀分布
290-
for col in range(columns):
291-
self.grid_layout.setColumnStretch(col, 1)
292273
finally:
293274
# 清除布局更新标志
294275
self._layout_update_in_progress = False
@@ -340,9 +321,6 @@ def _clear_grid_layout(self):
340321

341322
def addContributorCard(self, contributor):
342323
"""添加单个贡献者卡片"""
343-
if not hasattr(self, "grid_layout") or self.grid_layout is None:
344-
return None
345-
346324
try:
347325
card = QWidget()
348326
card.setObjectName("contributorCard")

app/view/another_window/remaining_list.py

Lines changed: 35 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import json
77
from typing import Dict, Any
88

9-
from PySide6.QtWidgets import QWidget, QVBoxLayout, QGridLayout
9+
from PySide6.QtWidgets import QWidget, QVBoxLayout
1010
from PySide6.QtGui import QFont
1111
from PySide6.QtCore import (
1212
Signal,
@@ -17,7 +17,7 @@
1717
QThreadPool,
1818
QObject,
1919
)
20-
from qfluentwidgets import SubtitleLabel, BodyLabel, CardWidget
20+
from qfluentwidgets import SubtitleLabel, BodyLabel, CardWidget, FlowLayout
2121
from loguru import logger
2222

2323
from app.tools.variable import (
@@ -301,10 +301,11 @@ def init_ui(self):
301301
self.count_label.setFont(QFont("", 12))
302302
self.main_layout.addWidget(self.count_label)
303303

304-
# 创建网格布局
305-
self.grid_layout = QGridLayout()
306-
self.grid_layout.setSpacing(STUDENT_CARD_SPACING)
307-
self.main_layout.addLayout(self.grid_layout)
304+
# 创建流式布局
305+
self.flow_layout = FlowLayout()
306+
self.flow_layout.setVerticalSpacing(STUDENT_CARD_SPACING)
307+
self.flow_layout.setHorizontalSpacing(STUDENT_CARD_SPACING)
308+
self.main_layout.addLayout(self.flow_layout)
308309

309310
# 初始化卡片列表
310311
self.cards = []
@@ -421,7 +422,7 @@ def update_ui(self):
421422

422423
# 清空现有卡片并准备异步渲染
423424
self.cards = []
424-
self._clear_grid_layout()
425+
self._clear_flow_layout()
425426

426427
# 将待渲染学生放入队列,启动增量渲染
427428
self._pending_students = list(self.students) if self.students else []
@@ -431,7 +432,7 @@ def update_ui(self):
431432

432433
def update_layout(self):
433434
"""更新布局"""
434-
if not self.grid_layout or not self.cards:
435+
if not self.flow_layout or not self.cards:
435436
return
436437

437438
# 检查是否需要更新布局
@@ -464,27 +465,17 @@ def update_layout(self):
464465
self.setUpdatesEnabled(False)
465466

466467
# 清空现有布局
467-
self._clear_grid_layout()
468+
self._clear_flow_layout()
468469

469-
# 计算列数
470-
window_width = max(self.width(), self.sizeHint().width())
471-
columns = self._calculate_columns(window_width)
472-
473-
# 添加卡片到网格布局
474-
for i, card in enumerate(self.cards):
475-
row = i // columns
476-
col = i % columns
477-
self.grid_layout.addWidget(card, row, col)
470+
# 添加卡片到流式布局
471+
for card in self.cards:
472+
self.flow_layout.addWidget(card)
478473
# 仅在控件当前不可见时显示,避免重复触发绘制
479474
if not card.isVisible():
480475
card.show()
481476

482-
# 设置列的伸缩因子,使卡片均匀分布
483-
for col in range(columns):
484-
self.grid_layout.setColumnStretch(col, 1)
485-
486477
logger.debug(
487-
f"布局更新完成: 宽度={window_width}, 列数={columns}, 卡片数={len(self.cards)}"
478+
f"布局更新完成: 宽度={current_width}, 卡片数={len(self.cards)}"
488479
)
489480
finally:
490481
# 清除布局更新标志
@@ -515,26 +506,17 @@ def update_layout(self):
515506
"Error calling update() after layout update (ignored): {}", e
516507
)
517508

518-
def _calculate_columns(self, width: int) -> int:
519-
"""根据窗口宽度和卡片尺寸动态计算列数"""
509+
def _clear_flow_layout(self):
510+
"""清空流式布局"""
511+
# 使用FlowLayout的removeAllWidgets方法清空布局
512+
self.flow_layout.removeAllWidgets()
513+
# 清空已记录的已添加卡片集合
520514
try:
521-
if width <= 0:
522-
return 1
523-
524-
# 计算可用宽度(减去左右边距)
525-
available_width = width - 40 # 左右各20px边距
526-
527-
# 所有卡片使用相同的尺寸
528-
card_actual_width = STUDENT_CARD_FIXED_WIDTH + STUDENT_CARD_SPACING
529-
max_cols = max(1, available_width // card_actual_width)
530-
531-
# 至少显示1列,且不超过一个合理上限
532-
return max(1, min(int(max_cols), 6))
515+
self._cards_set.clear()
533516
except Exception as e:
534517
from loguru import logger
535518

536-
logger.exception("Error calculating columns (fallback to 1): {}", e)
537-
return 1
519+
logger.exception("Error clearing cards set (ignored): {}", e)
538520

539521
def _start_incremental_render(self):
540522
"""使用 QThreadPool 启动后台任务,按批准备数据并通过信号通知主线程创建控件"""
@@ -724,69 +706,33 @@ def _on_batch_ready(self, reporter, batch: list):
724706
self.cards.append(card)
725707
self._cards_set.add(key)
726708

727-
# 将新卡片添加到布局(只放置尚未加入布局的卡片)
709+
# 将新卡片添加到布局
728710
try:
729-
columns = self._calculate_columns(
730-
max(self.width(), self.sizeHint().width())
731-
)
732-
733-
for i, card in enumerate(list(self.cards)):
734-
# 如果卡片已经在布局中则跳过
711+
for card in list(self.cards):
712+
# 确保卡片不在另一个父控件下
735713
try:
736-
if self.grid_layout.indexOf(card) != -1:
737-
continue
714+
if card.parent() is not None and card.parent() is not self:
715+
card.setParent(None)
738716
except Exception as e:
739717
from loguru import logger
740-
741-
logger.exception(
742-
"Error checking grid_layout.indexOf (ignored): {}", e
743-
)
744-
745-
row = i // columns
746-
col = i % columns
747-
748-
# 如果目标格位已有其它控件,先移除避免重叠
718+
logger.exception("Error resetting card parent (ignored): {}", e)
719+
720+
# 如果卡片已经在布局中则跳过
749721
try:
750-
existing_item = self.grid_layout.itemAtPosition(row, col)
751-
if existing_item is not None:
752-
existing_widget = existing_item.widget()
753-
if existing_widget is not None and existing_widget is not card:
754-
try:
755-
self.grid_layout.removeWidget(existing_widget)
756-
except Exception as e:
757-
from loguru import logger
758-
759-
logger.exception(
760-
"Error removing existing widget from grid (ignored): {}",
761-
e,
762-
)
763-
try:
764-
existing_widget.hide()
765-
except Exception as e:
766-
from loguru import logger
767-
768-
logger.exception(
769-
"Error hiding existing widget (ignored): {}", e
770-
)
722+
if self.flow_layout.indexOf(card) != -1:
723+
continue
771724
except Exception as e:
772725
from loguru import logger
773-
774-
logger.exception(
775-
"Error handling existing widget in grid (ignored): {}", e
776-
)
777-
726+
logger.exception("Error checking flow_layout.indexOf (ignored): {}", e)
727+
778728
try:
779-
self.grid_layout.addWidget(card, row, col)
729+
self.flow_layout.addWidget(card)
780730
if not card.isVisible():
781731
card.show()
782732
except Exception:
783-
logger.exception("向网格添加卡片失败")
784-
785-
for col in range(columns):
786-
self.grid_layout.setColumnStretch(col, 1)
733+
logger.exception("向流式布局添加卡片失败")
787734
except Exception as e:
788735
from loguru import logger
789-
790736
logger.exception("增量渲染时布局更新失败: {}", e)
791737

792738
def _on_render_finished(self, reporter):

0 commit comments

Comments
 (0)