软件支持图片拖动和图片粘贴
Showing
2 changed files
with
285 additions
and
16 deletions
| ... | @@ -3,5 +3,5 @@ | ... | @@ -3,5 +3,5 @@ |
| 3 | <component name="Black"> | 3 | <component name="Black"> |
| 4 | <option name="sdkName" value="Python 3.9 (GoogleNanoBananaApp) (2)" /> | 4 | <option name="sdkName" value="Python 3.9 (GoogleNanoBananaApp) (2)" /> |
| 5 | </component> | 5 | </component> |
| 6 | <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (GoogleNanoBananaApp)" project-jdk-type="Python SDK" /> | 6 | <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (Nano_Banana_App)" project-jdk-type="Python SDK" /> |
| 7 | </project> | 7 | </project> |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -12,8 +12,8 @@ from PySide6.QtWidgets import ( | ... | @@ -12,8 +12,8 @@ from PySide6.QtWidgets import ( |
| 12 | QListWidget, QListWidgetItem, QTabWidget, QSplitter, | 12 | QListWidget, QListWidgetItem, QTabWidget, QSplitter, |
| 13 | QMenu, QProgressBar | 13 | QMenu, QProgressBar |
| 14 | ) | 14 | ) |
| 15 | from PySide6.QtCore import Qt, QThread, Signal, QSize, QTimer | 15 | from PySide6.QtCore import Qt, QThread, Signal, QSize, QTimer, QMimeData |
| 16 | from PySide6.QtGui import QPixmap, QFont, QIcon, QDesktopServices, QAction, QImage | 16 | from PySide6.QtGui import QPixmap, QFont, QIcon, QDesktopServices, QAction, QImage, QDragEnterEvent, QDropEvent |
| 17 | from PySide6.QtCore import QUrl | 17 | from PySide6.QtCore import QUrl |
| 18 | 18 | ||
| 19 | import base64 | 19 | import base64 |
| ... | @@ -109,6 +109,7 @@ def hash_password(password: str) -> str: | ... | @@ -109,6 +109,7 @@ def hash_password(password: str) -> str: |
| 109 | 109 | ||
| 110 | class DatabaseManager: | 110 | class DatabaseManager: |
| 111 | """数据库连接管理类""" | 111 | """数据库连接管理类""" |
| 112 | |||
| 112 | def __init__(self, db_config): | 113 | def __init__(self, db_config): |
| 113 | self.config = db_config | 114 | self.config = db_config |
| 114 | self.logger = logging.getLogger(__name__) | 115 | self.logger = logging.getLogger(__name__) |
| ... | @@ -317,7 +318,7 @@ class HistoryManager: | ... | @@ -317,7 +318,7 @@ class HistoryManager: |
| 317 | # 保存参考图片 | 318 | # 保存参考图片 |
| 318 | reference_image_paths = [] | 319 | reference_image_paths = [] |
| 319 | for i, ref_img_bytes in enumerate(reference_images): | 320 | for i, ref_img_bytes in enumerate(reference_images): |
| 320 | ref_path = record_dir / f"reference_{i+1}.png" | 321 | ref_path = record_dir / f"reference_{i + 1}.png" |
| 321 | with open(ref_path, 'wb') as f: | 322 | with open(ref_path, 'wb') as f: |
| 322 | f.write(ref_img_bytes) | 323 | f.write(ref_img_bytes) |
| 323 | reference_image_paths.append(ref_path) | 324 | reference_image_paths.append(ref_path) |
| ... | @@ -830,6 +831,123 @@ class LoginDialog(QDialog): | ... | @@ -830,6 +831,123 @@ class LoginDialog(QDialog): |
| 830 | return getattr(self, 'current_password_hash', '') | 831 | return getattr(self, 'current_password_hash', '') |
| 831 | 832 | ||
| 832 | 833 | ||
| 834 | class DragDropScrollArea(QScrollArea): | ||
| 835 | """自定义支持拖拽的图像滚动区域""" | ||
| 836 | |||
| 837 | def __init__(self, parent=None): | ||
| 838 | super().__init__(parent) | ||
| 839 | self.setAcceptDrops(True) | ||
| 840 | self.parent_window = parent | ||
| 841 | self.setStyleSheet(""" | ||
| 842 | QScrollArea { | ||
| 843 | border: 2px dashed #e5e5e5; | ||
| 844 | border-radius: 8px; | ||
| 845 | background-color: #fafafa; | ||
| 846 | } | ||
| 847 | QScrollArea:hover { | ||
| 848 | border-color: #007AFF; | ||
| 849 | background-color: #f0f8ff; | ||
| 850 | } | ||
| 851 | """) | ||
| 852 | |||
| 853 | def dragEnterEvent(self, event: QDragEnterEvent): | ||
| 854 | """拖拽进入事件处理""" | ||
| 855 | mime_data = event.mimeData() | ||
| 856 | |||
| 857 | # 检查是否包含文件URL | ||
| 858 | if mime_data.hasUrls(): | ||
| 859 | urls = mime_data.urls() | ||
| 860 | for url in urls: | ||
| 861 | if url.isLocalFile(): | ||
| 862 | file_path = url.toLocalFile() | ||
| 863 | if self.is_valid_image_file(file_path): | ||
| 864 | event.acceptProposedAction() | ||
| 865 | self.setStyleSheet(""" | ||
| 866 | QScrollArea { | ||
| 867 | border: 2px dashed #007AFF; | ||
| 868 | border-radius: 8px; | ||
| 869 | background-color: #e6f3ff; | ||
| 870 | } | ||
| 871 | """) | ||
| 872 | return | ||
| 873 | |||
| 874 | # 检查剪贴板图像 | ||
| 875 | if mime_data.hasImage(): | ||
| 876 | event.acceptProposedAction() | ||
| 877 | self.setStyleSheet(""" | ||
| 878 | QScrollArea { | ||
| 879 | border: 2px dashed #007AFF; | ||
| 880 | border-radius: 8px; | ||
| 881 | background-color: #e6f3ff; | ||
| 882 | } | ||
| 883 | """) | ||
| 884 | return | ||
| 885 | |||
| 886 | event.ignore() | ||
| 887 | |||
| 888 | def dragLeaveEvent(self, event): | ||
| 889 | """拖拽离开事件处理""" | ||
| 890 | self.setStyleSheet(""" | ||
| 891 | QScrollArea { | ||
| 892 | border: 2px dashed #e5e5e5; | ||
| 893 | border-radius: 8px; | ||
| 894 | background-color: #fafafa; | ||
| 895 | } | ||
| 896 | QScrollArea:hover { | ||
| 897 | border-color: #007AFF; | ||
| 898 | background-color: #f0f8ff; | ||
| 899 | } | ||
| 900 | """) | ||
| 901 | |||
| 902 | def dropEvent(self, event: QDropEvent): | ||
| 903 | """拖拽放置事件处理""" | ||
| 904 | mime_data = event.mimeData() | ||
| 905 | |||
| 906 | # 重置样式 | ||
| 907 | self.setStyleSheet(""" | ||
| 908 | QScrollArea { | ||
| 909 | border: 2px dashed #e5e5e5; | ||
| 910 | border-radius: 8px; | ||
| 911 | background-color: #fafafa; | ||
| 912 | } | ||
| 913 | QScrollArea:hover { | ||
| 914 | border-color: #007AFF; | ||
| 915 | background-color: #f0f8ff; | ||
| 916 | } | ||
| 917 | """) | ||
| 918 | |||
| 919 | # 处理文件拖拽 | ||
| 920 | if mime_data.hasUrls(): | ||
| 921 | urls = mime_data.urls() | ||
| 922 | image_files = [] | ||
| 923 | |||
| 924 | for url in urls: | ||
| 925 | if url.isLocalFile(): | ||
| 926 | file_path = url.toLocalFile() | ||
| 927 | if self.is_valid_image_file(file_path): | ||
| 928 | image_files.append(file_path) | ||
| 929 | |||
| 930 | if image_files: | ||
| 931 | self.parent_window.add_image_files(image_files) | ||
| 932 | event.acceptProposedAction() | ||
| 933 | return | ||
| 934 | |||
| 935 | # 处理剪贴板图像拖拽 | ||
| 936 | if mime_data.hasImage(): | ||
| 937 | image = mime_data.imageData() | ||
| 938 | if image and not image.isNull(): | ||
| 939 | self.parent_window.add_clipboard_image(image) | ||
| 940 | event.acceptProposedAction() | ||
| 941 | return | ||
| 942 | |||
| 943 | event.ignore() | ||
| 944 | |||
| 945 | def is_valid_image_file(self, file_path: str) -> bool: | ||
| 946 | """检查文件是否为有效的图像文件""" | ||
| 947 | valid_extensions = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'} | ||
| 948 | return Path(file_path).suffix.lower() in valid_extensions | ||
| 949 | |||
| 950 | |||
| 833 | class ImageGeneratorWindow(QMainWindow): | 951 | class ImageGeneratorWindow(QMainWindow): |
| 834 | """Qt-based main application window""" | 952 | """Qt-based main application window""" |
| 835 | 953 | ||
| ... | @@ -1013,7 +1131,8 @@ class ImageGeneratorWindow(QMainWindow): | ... | @@ -1013,7 +1131,8 @@ class ImageGeneratorWindow(QMainWindow): |
| 1013 | print(f"Failed to load bundled config: {e}") | 1131 | print(f"Failed to load bundled config: {e}") |
| 1014 | 1132 | ||
| 1015 | if not self.api_key: | 1133 | if not self.api_key: |
| 1016 | QMessageBox.warning(self, "警告", f"未找到API密钥\n配置文件位置: {config_path}\n\n请在应用中输入API密钥或手动编辑配置文件") | 1134 | QMessageBox.warning(self, "警告", |
| 1135 | f"未找到API密钥\n配置文件位置: {config_path}\n\n请在应用中输入API密钥或手动编辑配置文件") | ||
| 1017 | 1136 | ||
| 1018 | def save_config(self, last_user=None): | 1137 | def save_config(self, last_user=None): |
| 1019 | """Save configuration to file""" | 1138 | """Save configuration to file""" |
| ... | @@ -1100,13 +1219,41 @@ class ImageGeneratorWindow(QMainWindow): | ... | @@ -1100,13 +1219,41 @@ class ImageGeneratorWindow(QMainWindow): |
| 1100 | upload_btn.clicked.connect(self.upload_images) | 1219 | upload_btn.clicked.connect(self.upload_images) |
| 1101 | upload_header.addWidget(upload_btn) | 1220 | upload_header.addWidget(upload_btn) |
| 1102 | 1221 | ||
| 1222 | # Paste button | ||
| 1223 | paste_btn = QPushButton("📋 粘贴图片") | ||
| 1224 | paste_btn.clicked.connect(self.paste_from_clipboard) | ||
| 1225 | paste_btn.setStyleSheet(""" | ||
| 1226 | QPushButton { | ||
| 1227 | background-color: #f0f0f0; | ||
| 1228 | border: 1px solid #d0d0d0; | ||
| 1229 | padding: 8px 16px; | ||
| 1230 | border-radius: 4px; | ||
| 1231 | font-size: 12px; | ||
| 1232 | min-width: 80px; | ||
| 1233 | } | ||
| 1234 | QPushButton:hover { | ||
| 1235 | background-color: #e8e8e8; | ||
| 1236 | border-color: #007AFF; | ||
| 1237 | } | ||
| 1238 | QPushButton:pressed { | ||
| 1239 | background-color: #d0d0d0; | ||
| 1240 | } | ||
| 1241 | """) | ||
| 1242 | upload_header.addWidget(paste_btn) | ||
| 1243 | |||
| 1103 | self.image_count_label = QLabel("已选择 0 张") | 1244 | self.image_count_label = QLabel("已选择 0 张") |
| 1104 | upload_header.addWidget(self.image_count_label) | 1245 | upload_header.addWidget(self.image_count_label) |
| 1105 | upload_header.addStretch() | 1246 | upload_header.addStretch() |
| 1106 | ref_layout.addLayout(upload_header) | 1247 | ref_layout.addLayout(upload_header) |
| 1107 | 1248 | ||
| 1108 | # Image preview scroll area | 1249 | # Drag and drop hint |
| 1109 | self.img_scroll = QScrollArea() | 1250 | hint_label = QLabel("💡 提示:可以直接拖拽图片到下方区域,或使用 Ctrl+V 粘贴截图") |
| 1251 | hint_label.setStyleSheet("QLabel { color: #666666; font-size: 11px; margin: 2px 0; }") | ||
| 1252 | hint_label.setWordWrap(True) | ||
| 1253 | ref_layout.addWidget(hint_label) | ||
| 1254 | |||
| 1255 | # Image preview scroll area with drag-and-drop support | ||
| 1256 | self.img_scroll = DragDropScrollArea(self) | ||
| 1110 | self.img_scroll.setWidgetResizable(True) | 1257 | self.img_scroll.setWidgetResizable(True) |
| 1111 | self.img_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) | 1258 | self.img_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) |
| 1112 | self.img_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) | 1259 | self.img_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) |
| ... | @@ -1299,7 +1446,8 @@ class ImageGeneratorWindow(QMainWindow): | ... | @@ -1299,7 +1446,8 @@ class ImageGeneratorWindow(QMainWindow): |
| 1299 | 1446 | ||
| 1300 | self.prompt_display = QLabel("请选择一个历史记录查看详情") | 1447 | self.prompt_display = QLabel("请选择一个历史记录查看详情") |
| 1301 | self.prompt_display.setWordWrap(True) | 1448 | self.prompt_display.setWordWrap(True) |
| 1302 | self.prompt_display.setStyleSheet("QLabel { padding: 8px; background-color: #f9f9f9; border: 1px solid #ddd; border-radius: 4px; }") | 1449 | self.prompt_display.setStyleSheet( |
| 1450 | "QLabel { padding: 8px; background-color: #f9f9f9; border: 1px solid #ddd; border-radius: 4px; }") | ||
| 1303 | prompt_layout.addWidget(self.prompt_display) | 1451 | prompt_layout.addWidget(self.prompt_display) |
| 1304 | 1452 | ||
| 1305 | prompt_group.setLayout(prompt_layout) | 1453 | prompt_group.setLayout(prompt_layout) |
| ... | @@ -1355,7 +1503,8 @@ class ImageGeneratorWindow(QMainWindow): | ... | @@ -1355,7 +1503,8 @@ class ImageGeneratorWindow(QMainWindow): |
| 1355 | self.generated_image_label.setAlignment(Qt.AlignCenter) | 1503 | self.generated_image_label.setAlignment(Qt.AlignCenter) |
| 1356 | self.generated_image_label.setMinimumSize(200, 200) # Larger size for generated image | 1504 | self.generated_image_label.setMinimumSize(200, 200) # Larger size for generated image |
| 1357 | self.generated_image_label.setMaximumSize(300, 300) | 1505 | self.generated_image_label.setMaximumSize(300, 300) |
| 1358 | self.generated_image_label.setStyleSheet("QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | 1506 | self.generated_image_label.setStyleSheet( |
| 1507 | "QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | ||
| 1359 | self.generated_image_label.mouseDoubleClickEvent = self.open_generated_image_from_history | 1508 | self.generated_image_label.mouseDoubleClickEvent = self.open_generated_image_from_history |
| 1360 | 1509 | ||
| 1361 | gen_layout.addWidget(self.generated_image_label) | 1510 | gen_layout.addWidget(self.generated_image_label) |
| ... | @@ -1445,6 +1594,121 @@ class ImageGeneratorWindow(QMainWindow): | ... | @@ -1445,6 +1594,121 @@ class ImageGeneratorWindow(QMainWindow): |
| 1445 | self.status_label.setText(f"● 已添加 {len(files)} 张参考图片") | 1594 | self.status_label.setText(f"● 已添加 {len(files)} 张参考图片") |
| 1446 | self.status_label.setStyleSheet("QLabel { color: #34C759; }") | 1595 | self.status_label.setStyleSheet("QLabel { color: #34C759; }") |
| 1447 | 1596 | ||
| 1597 | def add_image_files(self, file_paths): | ||
| 1598 | """添加图像文件到上传列表(用于拖拽功能)""" | ||
| 1599 | if not file_paths: | ||
| 1600 | return | ||
| 1601 | |||
| 1602 | added_count = 0 | ||
| 1603 | for file_path in file_paths: | ||
| 1604 | try: | ||
| 1605 | if self.validate_image_file(file_path): | ||
| 1606 | self.uploaded_images.append(file_path) | ||
| 1607 | added_count += 1 | ||
| 1608 | else: | ||
| 1609 | self.logger.warning(f"无效的图像文件: {file_path}") | ||
| 1610 | except Exception as e: | ||
| 1611 | self.logger.error(f"添加图片失败: {file_path}, 错误: {str(e)}") | ||
| 1612 | |||
| 1613 | if added_count > 0: | ||
| 1614 | self.update_image_preview() | ||
| 1615 | self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张") | ||
| 1616 | self.status_label.setText(f"● 已通过拖拽添加 {added_count} 张参考图片") | ||
| 1617 | self.status_label.setStyleSheet("QLabel { color: #34C759; }") | ||
| 1618 | else: | ||
| 1619 | QMessageBox.warning(self, "警告", "没有找到有效的图片文件") | ||
| 1620 | |||
| 1621 | def add_clipboard_image(self, image): | ||
| 1622 | """添加剪贴板图像(用于拖拽和粘贴功能)""" | ||
| 1623 | try: | ||
| 1624 | # 生成临时文件名 | ||
| 1625 | timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | ||
| 1626 | temp_dir = Path(tempfile.gettempdir()) / "nano_banana_app" | ||
| 1627 | temp_dir.mkdir(exist_ok=True) | ||
| 1628 | |||
| 1629 | # 根据图像格式选择文件扩展名 | ||
| 1630 | file_extension = ".png" # 默认使用PNG格式 | ||
| 1631 | if image.format() == QImage.Format_RGB32: | ||
| 1632 | file_extension = ".bmp" | ||
| 1633 | elif image.format() == QImage.Format_RGB888: | ||
| 1634 | file_extension = ".jpg" | ||
| 1635 | |||
| 1636 | temp_file_path = temp_dir / f"clipboard_{timestamp}{file_extension}" | ||
| 1637 | |||
| 1638 | # 保存图像到临时文件 | ||
| 1639 | if image.save(str(temp_file_path)): | ||
| 1640 | self.uploaded_images.append(str(temp_file_path)) | ||
| 1641 | self.update_image_preview() | ||
| 1642 | self.image_count_label.setText(f"已选择 {len(self.uploaded_images)} 张") | ||
| 1643 | self.status_label.setText("● 已添加剪贴板图片") | ||
| 1644 | self.status_label.setStyleSheet("QLabel { color: #34C759; }") | ||
| 1645 | self.logger.info(f"剪贴板图片已保存到: {temp_file_path}") | ||
| 1646 | else: | ||
| 1647 | QMessageBox.critical(self, "错误", "无法保存剪贴板图片") | ||
| 1648 | |||
| 1649 | except Exception as e: | ||
| 1650 | self.logger.error(f"添加剪贴板图片失败: {str(e)}") | ||
| 1651 | QMessageBox.critical(self, "错误", f"添加剪贴板图片失败: {str(e)}") | ||
| 1652 | |||
| 1653 | def paste_from_clipboard(self): | ||
| 1654 | """从剪贴板粘贴图像""" | ||
| 1655 | clipboard = QApplication.clipboard() | ||
| 1656 | |||
| 1657 | # 检查剪贴板中是否有图像 | ||
| 1658 | if clipboard.mimeData().hasImage(): | ||
| 1659 | image = clipboard.image() | ||
| 1660 | if not image.isNull(): | ||
| 1661 | self.add_clipboard_image(image) | ||
| 1662 | else: | ||
| 1663 | QMessageBox.information(self, "信息", "剪贴板中没有有效的图片") | ||
| 1664 | else: | ||
| 1665 | QMessageBox.information(self, "信息", "剪贴板中没有图片,请先复制一张图片") | ||
| 1666 | |||
| 1667 | def validate_image_file(self, file_path: str) -> bool: | ||
| 1668 | """验证图像文件""" | ||
| 1669 | try: | ||
| 1670 | # 检查文件是否存在 | ||
| 1671 | if not Path(file_path).exists(): | ||
| 1672 | return False | ||
| 1673 | |||
| 1674 | # 检查文件扩展名 | ||
| 1675 | valid_extensions = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'} | ||
| 1676 | if Path(file_path).suffix.lower() not in valid_extensions: | ||
| 1677 | return False | ||
| 1678 | |||
| 1679 | # 尝试加载图像以验证文件完整性 | ||
| 1680 | pixmap = QPixmap(file_path) | ||
| 1681 | if pixmap.isNull(): | ||
| 1682 | return False | ||
| 1683 | |||
| 1684 | # 检查文件大小(限制为10MB) | ||
| 1685 | file_size = Path(file_path).stat().st_size | ||
| 1686 | if file_size > 10 * 1024 * 1024: # 10MB | ||
| 1687 | QMessageBox.warning(self, "警告", f"图片文件过大: {file_path}\n请选择小于10MB的图片") | ||
| 1688 | return False | ||
| 1689 | |||
| 1690 | return True | ||
| 1691 | |||
| 1692 | except Exception as e: | ||
| 1693 | self.logger.error(f"图像文件验证失败: {file_path}, 错误: {str(e)}") | ||
| 1694 | return False | ||
| 1695 | |||
| 1696 | def keyPressEvent(self, event): | ||
| 1697 | """处理键盘事件""" | ||
| 1698 | # Ctrl+V 粘贴 | ||
| 1699 | if event.key() == Qt.Key_V and event.modifiers() == Qt.ControlModifier: | ||
| 1700 | self.paste_from_clipboard() | ||
| 1701 | event.accept() | ||
| 1702 | return | ||
| 1703 | |||
| 1704 | # Cmd+V 粘贴 (macOS) | ||
| 1705 | elif event.key() == Qt.Key_V and event.modifiers() == Qt.MetaModifier: | ||
| 1706 | self.paste_from_clipboard() | ||
| 1707 | event.accept() | ||
| 1708 | return | ||
| 1709 | |||
| 1710 | super().keyPressEvent(event) | ||
| 1711 | |||
| 1448 | def update_image_preview(self): | 1712 | def update_image_preview(self): |
| 1449 | """Update image preview thumbnails""" | 1713 | """Update image preview thumbnails""" |
| 1450 | # Clear existing previews | 1714 | # Clear existing previews |
| ... | @@ -1707,7 +1971,6 @@ class ImageGeneratorWindow(QMainWindow): | ... | @@ -1707,7 +1971,6 @@ class ImageGeneratorWindow(QMainWindow): |
| 1707 | except Exception as e: | 1971 | except Exception as e: |
| 1708 | QMessageBox.critical(self, "错误", f"保存失败: {str(e)}") | 1972 | QMessageBox.critical(self, "错误", f"保存失败: {str(e)}") |
| 1709 | 1973 | ||
| 1710 | |||
| 1711 | def refresh_history(self): | 1974 | def refresh_history(self): |
| 1712 | """Refresh the history list""" | 1975 | """Refresh the history list""" |
| 1713 | self.history_list.clear() | 1976 | self.history_list.clear() |
| ... | @@ -1954,18 +2217,22 @@ class ImageGeneratorWindow(QMainWindow): | ... | @@ -1954,18 +2217,22 @@ class ImageGeneratorWindow(QMainWindow): |
| 1954 | Qt.SmoothTransformation | 2217 | Qt.SmoothTransformation |
| 1955 | ) | 2218 | ) |
| 1956 | self.generated_image_label.setPixmap(scaled_pixmap) | 2219 | self.generated_image_label.setPixmap(scaled_pixmap) |
| 1957 | self.generated_image_label.setStyleSheet("QLabel { border: 1px solid #ddd; background-color: white; }") | 2220 | self.generated_image_label.setStyleSheet( |
| 2221 | "QLabel { border: 1px solid #ddd; background-color: white; }") | ||
| 1958 | self.current_generated_image_path = image_path | 2222 | self.current_generated_image_path = image_path |
| 1959 | else: | 2223 | else: |
| 1960 | self.generated_image_label.setText("图片加载失败") | 2224 | self.generated_image_label.setText("图片加载失败") |
| 1961 | self.generated_image_label.setStyleSheet("QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | 2225 | self.generated_image_label.setStyleSheet( |
| 2226 | "QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | ||
| 1962 | except Exception as e: | 2227 | except Exception as e: |
| 1963 | print(f"Failed to load generated image {image_path}: {e}") | 2228 | print(f"Failed to load generated image {image_path}: {e}") |
| 1964 | self.generated_image_label.setText("图片加载失败") | 2229 | self.generated_image_label.setText("图片加载失败") |
| 1965 | self.generated_image_label.setStyleSheet("QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | 2230 | self.generated_image_label.setStyleSheet( |
| 2231 | "QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | ||
| 1966 | else: | 2232 | else: |
| 1967 | self.generated_image_label.setText("图片文件不存在") | 2233 | self.generated_image_label.setText("图片文件不存在") |
| 1968 | self.generated_image_label.setStyleSheet("QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | 2234 | self.generated_image_label.setStyleSheet( |
| 2235 | "QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | ||
| 1969 | 2236 | ||
| 1970 | def clear_details_panel(self): | 2237 | def clear_details_panel(self): |
| 1971 | """Clear the details panel""" | 2238 | """Clear the details panel""" |
| ... | @@ -1986,7 +2253,8 @@ class ImageGeneratorWindow(QMainWindow): | ... | @@ -1986,7 +2253,8 @@ class ImageGeneratorWindow(QMainWindow): |
| 1986 | 2253 | ||
| 1987 | self.generated_image_label.setText("请选择一个历史记录查看生成图片") | 2254 | self.generated_image_label.setText("请选择一个历史记录查看生成图片") |
| 1988 | self.generated_image_label.setPixmap(QPixmap()) | 2255 | self.generated_image_label.setPixmap(QPixmap()) |
| 1989 | self.generated_image_label.setStyleSheet("QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | 2256 | self.generated_image_label.setStyleSheet( |
| 2257 | "QLabel { background-color: #f5f5f5; border: 1px solid #ddd; color: #999; }") | ||
| 1990 | 2258 | ||
| 1991 | def copy_prompt_text(self): | 2259 | def copy_prompt_text(self): |
| 1992 | """Copy the prompt text to clipboard""" | 2260 | """Copy the prompt text to clipboard""" |
| ... | @@ -2027,7 +2295,8 @@ class ImageGeneratorWindow(QMainWindow): | ... | @@ -2027,7 +2295,8 @@ class ImageGeneratorWindow(QMainWindow): |
| 2027 | 2295 | ||
| 2028 | class ImageGenerationWorker(QThread): | 2296 | class ImageGenerationWorker(QThread): |
| 2029 | """Worker thread for image generation""" | 2297 | """Worker thread for image generation""" |
| 2030 | finished = Signal(bytes, str, list, str, str, str) # image_bytes, prompt, reference_images, aspect_ratio, image_size, model | 2298 | finished = Signal(bytes, str, list, str, str, |
| 2299 | str) # image_bytes, prompt, reference_images, aspect_ratio, image_size, model | ||
| 2031 | error = Signal(str) | 2300 | error = Signal(str) |
| 2032 | progress = Signal(str) | 2301 | progress = Signal(str) |
| 2033 | 2302 | ... | ... |
-
Please register or sign in to post a comment