A modern, production-grade Student Information & Grade Management System
built with Python 3 + PyQt5.
| Area | Original (v1βv2) | v3 (This Version) |
|---|---|---|
| Architecture | Monolithic single file, spaghetti UI logic | Layered: core/, ui/, utils/, tests/ |
| Database | Raw SQL string concatenation (SQL injection risk) | Parameterized queries, WAL mode, indexes, triggers |
| Auth | Plain-text password comparison | SHA-256 hashing |
| UI layout | Absolute pixel positioning | Proper layout managers, responsive sizing |
| Forms | Duplicate add/edit/delete logic per page | Single FormDialog reused for both add & edit |
| Image handling | os.startfile() (Windows-only) |
Cross-platform subprocess viewer |
| Search | None / broken | Full-text search across all relevant columns |
| Statistics | None | New Analytics page with bar charts + top students |
| Code duplication | QMessageBox.setStyleSheet() repeated 30+ times |
show_message() helper, one place to change |
| Tests | None | 30+ pytest unit tests covering DB + validators |
| Documentation | None | This README + in-code docstrings throughout |
Student_archive/
βββ main.py # Entry point
βββ requirements.txt
βββ README.md
β
βββ core/
β βββ __init__.py
β βββ database.py # All DB logic β parameterized, context-managed
β
βββ ui/
β βββ __init__.py
β βββ theme.py # Design system: colors, fonts, global QSS
β βββ widgets.py # Reusable components (StatCard, SearchBar, Table, β¦)
β βββ login_window.py # Frameless dark login screen
β βββ main_window.py # App shell: sidebar + stacked pages
β βββ pages/
β βββ __init__.py
β βββ students_page.py # Students CRUD + detail panel
β βββ grades_page.py # Grades CRUD
β βββ stats_page.py # Analytics dashboard
β
βββ utils/
β βββ __init__.py
β βββ validators.py # Email, phone, age, required-field validators
β
βββ data/ # Auto-created at runtime
β βββ Student_archive.db
β βββ admin.db
β
βββ tests/
βββ __init__.py
βββ test_database.py # 30+ unit tests for core layer
- Python 3.9+
- pip
# Clone the repository
git clone https://github.com/alanhasn/StudentSimpleArchive-Desktop-App-Using-PyQt5-Modern.git
cd StudentSimpleArchive-Desktop-App-Using-PyQt5-Modern
# Create a virtual environment (recommended)
python -m venv venv
source venv/bin/activate # Linux/macOS
venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
# Run the application
python main.py| Field | Value |
|---|---|
| Username | admin |
| Password | admin123 |
β οΈ Change the default password immediately after first login.
A future release will prompt for this on first run.
| Column | Type | Notes |
|---|---|---|
id |
INTEGER PK | Auto-increment |
name |
TEXT | Required |
last_name |
TEXT | Required |
email |
TEXT UNIQUE | Optional, validated |
phone_number |
TEXT | Optional |
country, city, region |
TEXT | Optional |
age, birthday |
TEXT | Optional |
gender, health, study, martial_status |
TEXT | Enum-constrained in UI |
native_language, mother_name, father_name |
TEXT | Optional |
image_data |
TEXT | Base64-encoded photo |
created_at, updated_at |
DATETIME | Auto-managed via trigger |
| Column | Type | Notes |
|---|---|---|
id |
INTEGER PK | Auto-increment |
student_id |
INTEGER | FK β students(id) ON DELETE CASCADE |
name, last_name |
TEXT | Denormalized for display convenience |
math_score, english_score, python_score, β¦ |
TEXT | Score or label |
| Column | Type | Notes |
|---|---|---|
id |
INTEGER PK | |
username |
TEXT UNIQUE | |
password |
TEXT | SHA-256 hash |
- Parameterized queries β all SQL uses
?placeholders; no string formatting in queries. - Password hashing β admin passwords are stored as SHA-256 hashes, never plain text.
- Input validation β email format, required fields, and age range are validated before any DB write.
- Foreign keys β
PRAGMA foreign_keys = ONenforced per connection. - WAL mode β SQLite Write-Ahead Logging enabled for better concurrency safety.
For a production deployment, upgrade password hashing from SHA-256 to bcrypt or argon2:
pip install bcryptThen replace
_hash_password()incore/database.py.
# From the project root
python -m pytest tests/ -v
# With coverage
pip install pytest-cov
python -m pytest tests/ --cov=core --cov=utils --cov-report=term-missingExpected output: 30+ tests passing covering auth, CRUD, search, stats, and validators.
- Frameless dark window, draggable
- Inline error feedback (no dialog popups for wrong password)
- Keyboard shortcut:
Enterto submit
- Sidebar navigation β Students / Grades / Statistics
- Students page β searchable table + right-side detail panel with photo, edit, delete
- Grades page β searchable table with per-subject score management
- Statistics page β summary cards, country/gender bar charts, subject progress bars, top-5 leaderboard
The original code called sqlite3.connect("archive.db") in dozens of UI event handlers. This meant:
- Connection lifecycle unmanaged (connections never closed properly)
- SQL injection surface spread across 30+ locations
- No single place to add logging, error handling, or migration logic
DatabaseManager consolidates all of this behind a context-managed connection (@contextmanager) and exposes typed methods that return plain Python dicts β the UI layer never sees a sqlite3.Row object.
The original had separate save_button(), change(), update_item(), and clean_fields() functions that duplicated ~80% of the same widget creation and validation code. A single StudentFormDialog(existing=None) handles both paths cleanly.
Qt stylesheets applied per-widget with inline strings create maintenance nightmares β changing a border radius means hunting through 50 files. A single stylesheet applied at QApplication level cascades to all children, and the design token variables (colors, font sizes) are defined once.
The application currently reads no environment variables β paths are relative to the project root. For a server deployment, these would be externalized:
| Variable | Default | Description |
|---|---|---|
SIMORX_DB_PATH |
data/simorx_archive.db |
Path to main database |
SIMORX_ADMIN_DB_PATH |
data/admin.db |
Path to admin credentials DB |
SIMORX_LOG_LEVEL |
INFO |
Python logging level |
Use PyInstaller to create a single executable:
pip install pyinstaller
pyinstaller --onefile --windowed --name "StudentArchive" main.pyThe dist/StudentArchive executable will include Python and all dependencies. The data/ folder should be distributed alongside it (or created on first run, which already happens automatically).
| Role | Person |
|---|---|
| Project Manager | Vorsynth |
| Development Lead | Vorsynth |
- Complete architecture overhaul: layered
core / ui / utils / tests - SQL injection vulnerabilities patched β all queries parameterized
- Hashed password storage (SHA-256)
- Modern QSS design system with sidebar navigation
- Statistics dashboard (new)
- 30+ unit tests (new)
- Cross-platform photo viewer
- Reusable form dialogs eliminating code duplication
- Full README and docstrings
- Original monolithic implementation
- Basic CRUD with raw SQL string formatting
- Absolute-positioned widgets
- No tests, no documentation