import os from PyQt6.QtWidgets import QLabel from PyQt6.QtCore import Qt class FinishedBooksMixin: """已读书籍网格相关逻辑。依赖: self.manager, self.find_book_cover, self.finishedGridLayout, self._on_finished_cover_clicked.""" def _populate_finished_books_grid(self): if not hasattr(self, 'finishedGridLayout'): return finished = self.manager.get_finished_books_this_year() # 清空旧 while self.finishedGridLayout.count(): item = self.finishedGridLayout.takeAt(0) w = item.widget() if w: w.setParent(None) if not finished: self.finishedGridLayout.addWidget(QLabel('今年暂无已读完书籍')) self._finished_widgets = [] return self._finished_widgets = [] thumb_w = 100 thumb_h = int(thumb_w * 1.3) for asset_id, info, fin_dt in finished: cover_path = self.find_book_cover(asset_id, info) if info else None cover_lab = QLabel() cover_lab.setAlignment(Qt.AlignmentFlag.AlignCenter) try: cover_lab.setFocusPolicy(Qt.FocusPolicy.NoFocus) cover_lab.setCursor(Qt.CursorShape.PointingHandCursor) except Exception: pass # 默认封面 if (not cover_path) or (not os.path.exists(cover_path)): default_cover = os.path.join(os.path.dirname(__file__), 'defaultcover.jpeg') if os.path.exists(default_cover): cover_path = default_cover if cover_path and os.path.exists(cover_path): from PyQt6.QtGui import QPixmap pm = QPixmap(cover_path) if not pm.isNull(): pm = pm.scaled(thumb_w, thumb_h, Qt.AspectRatioMode.IgnoreAspectRatio, Qt.TransformationMode.SmoothTransformation) cover_lab.setPixmap(pm) else: cover_lab.setText('无封面') else: cover_lab.setText('无封面') name_full = info.get('displayname') or info.get('itemname') or asset_id name_short = name_full[:8] + '…' if len(name_full) > 8 else name_full name_lab = QLabel(name_short) author = info.get('author','') tip = name_full if not author else f"{name_full}\n{author}" cover_lab.setToolTip(tip) name_lab.setToolTip(tip) def make_click_handler(aid): def handler(event): if event.button() == Qt.MouseButton.LeftButton: self._on_finished_cover_clicked(aid) return handler cover_lab.mousePressEvent = make_click_handler(asset_id) name_lab.setWordWrap(True) name_lab.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop) self._finished_widgets.append((cover_lab, name_lab)) self._relayout_finished_grid() def _relayout_finished_grid(self): if not hasattr(self, 'finishedGridLayout') or not hasattr(self, '_finished_widgets'): return scroll_area = getattr(self, 'finished_scroll_area', None) if scroll_area is not None: viewport = scroll_area.viewport() width = viewport.width() else: width = self.width() thumb_w = 100 h_gap = 12 min_cols = 2 cols = max(min_cols, width // (thumb_w + h_gap)) while self.finishedGridLayout.count(): item = self.finishedGridLayout.takeAt(0) w = item.widget() if w: w.setParent(None) row = 0 col = 0 for cover_lab, name_lab in self._finished_widgets: self.finishedGridLayout.addWidget(cover_lab, row*2, col) self.finishedGridLayout.addWidget(name_lab, row*2+1, col) col += 1 if col >= cols: col = 0 row += 1