Spec: Qt-based GUI Implementation
Overview
Specification for migrating the application from tkinter to PySide6 to resolve macOS rendering issues and provide a modern, cross-platform GUI framework.
ADDED Requirements
Requirement: PySide6 Framework Integration
ID: qt-gui-001
The application MUST use PySide6 (Qt 6 for Python) as the GUI framework, replacing tkinter entirely. The framework SHALL be version 6.6.0 or higher.
Scenario: PySide6 is installed and importable
Given the application is deployed on a system When the Python interpreter attempts to import PySide6 modules Then the import MUST succeed without errors And the version SHALL be 6.6.0 or higher And all required Qt modules SHALL be available (QtWidgets, QtCore, QtGui)
Scenario: No tkinter dependencies remain
Given the migrated application code When analyzing all imports Then no tkinter or ttk imports SHALL exist And no tk.* or ttk.* class references SHALL exist And all GUI code SHALL use PySide6.Qt* classes
Requirement: LoginDialog Cross-Platform Visibility
ID: qt-gui-002
The login dialog MUST be fully visible and functional on macOS, Windows, and Linux platforms. All UI elements SHALL render with native platform appearance.
Scenario: LoginDialog renders correctly on macOS
Given the application is launched on macOS When the LoginDialog is displayed Then all UI elements SHALL be visible (title, labels, input fields, checkboxes, button) And the dialog SHALL have a white background And the dialog SHALL use macOS native window decorations And all text SHALL be readable with proper contrast And input fields SHALL accept keyboard input And the cursor SHALL be visible in focused input fields
Scenario: LoginDialog renders correctly on Windows
Given the application is launched on Windows When the LoginDialog is displayed Then all UI elements SHALL be visible And the dialog SHALL use Windows native window decorations And the styling SHALL match Windows UI guidelines And high-DPI displays SHALL scale correctly
Scenario: LoginDialog authentication functionality preserved
Given the LoginDialog is displayed with valid database configuration When the user enters valid credentials and clicks "登录" Then the database authentication SHALL execute And on success, the dialog SHALL return QDialog.Accepted And the authenticated username and password hash SHALL be accessible And on failure, an error message SHALL display in the dialog
Requirement: ImageGeneratorWindow Functional Parity
ID: qt-gui-003
The main application window MUST preserve all functionality from the tkinter version while using Qt widgets and layouts.
Scenario: All features from tkinter version are available
Given the Qt-based ImageGeneratorWindow Then reference image upload SHALL work And image preview thumbnails SHALL display And prompt text input SHALL work And prompt favorites (save/load/delete) SHALL work And aspect ratio selection SHALL work And image size selection SHALL work And image generation SHALL work via Gemini API And generated image preview SHALL display And image download SHALL work And configuration save/load SHALL work
Scenario: Reference images can be uploaded and displayed
Given the ImageGeneratorWindow is displayed When the user clicks "+ 添加图片" Then a QFileDialog SHALL open for image selection When the user selects one or more image files Then each image SHALL appear as a 100x100 thumbnail And each thumbnail SHALL have a delete button And the image count label SHALL update And clicking delete SHALL remove the thumbnail
Scenario: Image generation works asynchronously
Given the user has entered a prompt When the user clicks "生成图片" Then image generation SHALL execute in a QThread (not main thread) And the UI SHALL remain responsive during generation And a status message SHALL indicate generation is in progress And on completion, the generated image SHALL display in the preview area And the "下载图片" button SHALL become enabled And on error, an error message SHALL display
Requirement: Qt Layout System Usage
ID: qt-gui-004
All UI layouts MUST use Qt's layout system (QVBoxLayout, QHBoxLayout, QFormLayout, QGridLayout) rather than absolute positioning. This ensures responsive, cross-platform compatibility.
Scenario: LoginDialog uses Qt layouts
Given the LoginDialog implementation Then the main structure SHALL use QVBoxLayout And username/password fields SHALL use QFormLayout And checkboxes SHALL use QHBoxLayout And no absolute positioning (setGeometry) SHALL be used And the dialog SHALL resize gracefully
Scenario: ImageGeneratorWindow uses Qt layouts
Given the ImageGeneratorWindow implementation Then the central widget SHALL use QVBoxLayout as main layout And content sections SHALL use appropriate nested layouts And the window SHALL be resizable And widgets SHALL expand/contract appropriately when resized
Requirement: Qt Styling with QSS
ID: qt-gui-005
The application MUST use Qt Style Sheets (QSS) for consistent, maintainable styling across all UI components.
Scenario: Consistent color scheme applied via QSS
Given the application windows and dialogs Then all styling SHALL use QSS (not programmatic setFont/setColor) And the color scheme SHALL match the original design:
- Background: #ffffff (white)
- Accent: #007AFF (blue)
- Hover: #0051D5 (darker blue)
- Text: #1d1d1f (dark gray)
- Secondary text: #666666 (medium gray)
- Input background: #fafafa (light gray)
- Error text: #ff3b30 (red) And fonts SHALL use "Segoe UI" or system default And the stylesheet SHALL be centralized for easy modification
Scenario: Buttons have hover states
Given any QPushButton in the application When the user hovers over the button Then the button background color SHALL change to the hover color And the cursor SHALL change to a pointing hand
Requirement: Asynchronous Operations with QThread
ID: qt-gui-006
All long-running operations (API calls, file I/O, database queries) MUST execute in QThread instances to prevent UI freezing.
Scenario: Image generation runs in background thread
Given the user initiates image generation When the generation process starts Then a QThread worker SHALL be created and started And the main thread (UI) SHALL remain responsive And the user SHALL be able to interact with other UI elements And the worker SHALL communicate via Qt signals (finished, error, progress) And UI updates SHALL occur in response to signals
Scenario: Database authentication runs asynchronously
Given the user clicks the login button When database authentication begins Then the operation SHOULD execute in a separate thread (optional for quick operations) Or the UI SHALL show a loading indicator during authentication And the UI SHALL not freeze
Requirement: Configuration Compatibility
ID: qt-gui-007
The Qt-based application MUST read and write configuration files in the same format as the tkinter version, ensuring seamless transition.
Scenario: Existing config.json is read correctly
Given a config.json file from the tkinter version exists When the Qt application loads Then the config SHALL be read successfully And api_key SHALL be loaded And saved_prompts SHALL be loaded And db_config SHALL be loaded And last_user and saved_password_hash SHALL be loaded
Scenario: Config changes are saved correctly
Given the user makes changes (adds favorite prompt, checks remember me, etc.) When the application saves configuration Then the config.json file SHALL be updated And the JSON structure SHALL match the tkinter version's format And the file SHALL be readable by the tkinter version (backwards compatible)
Requirement: Native File Dialogs
ID: qt-gui-008
The application MUST use Qt's native file dialogs (QFileDialog) which provide platform-specific file selection interfaces.
Scenario: Image upload uses native file dialog
Given the user clicks "+ 添加图片" When QFileDialog.getOpenFileNames is called Then the system's native file picker SHALL appear And on macOS, it SHALL use the macOS file picker UI And on Windows, it SHALL use the Windows file picker UI And the dialog SHALL filter to show image files (png, jpg, jpeg, gif, bmp)
Scenario: Image save uses native save dialog
Given the user clicks "下载图片" When QFileDialog.getSaveFileName is called Then the system's native save dialog SHALL appear And the default filename SHALL be timestamp-based (YYYYMMDDHHMMSS.png) And the user can choose the save location and filename
Requirement: Error Handling and User Feedback
ID: qt-gui-009
The application MUST provide clear error messages and user feedback using Qt's message box and status display mechanisms.
Scenario: Error messages display in QMessageBox
Given an error occurs (API failure, file I/O error, etc.) When the error is encountered Then a QMessageBox SHALL display with the error details And the message box SHALL be modal (blocks interaction until dismissed) And the message SHALL be in Chinese (matching original UI) And the severity SHALL be appropriate (Critical, Warning, Information)
Scenario: Status updates display in status label
Given operations are in progress When status changes (generating image, uploading, saving, etc.) Then the status QLabel SHALL update with the current status And the status text SHALL include an indicator (● symbol) And the color SHALL indicate status (blue=in progress, green=success, red=error)
MODIFIED Requirements
Requirement: Database Authentication Implementation
ID: qt-gui-010
Database authentication MUST function identically to the tkinter version, with the same SQL queries, password hashing, and result handling, but using Qt widgets for UI.
Scenario: Authentication logic unchanged
Given the DatabaseManager class from the tkinter version Then the class SHOULD remain unchanged (works with Qt) And the hash_password function SHOULD remain unchanged And the SQL queries SHOULD remain identical And only the UI response (show dialog, update labels) SHALL use Qt widgets
REMOVED Requirements
Requirement: tkinter Framework Usage
ID: tkinter-001 (REMOVED)
The application no longer uses tkinter. All tkinter-based requirements are superseded by Qt requirements above.
Cross-References
- qt-gui-002 depends on qt-gui-001 (Qt must be installed first)
- qt-gui-003 depends on qt-gui-006 (async operations required for features)
- qt-gui-005 supports qt-gui-002 and qt-gui-003 (styling makes UI visible and polished)
- qt-gui-007 ensures qt-gui-010 works (config needed for auth)