Skip to content

17. (П8) Реалізація багатовіконного застосунку: нотатки в окремих вікнах

Передумови

Завдання

Перетворити менеджер нотаток із практичної 7 на багатовіконний застосунок. Додається три типи вікон:

  • головне вікно — список нотаток і редактор; таких вікон можна відкрити скільки завгодно;
  • вікно нотатки — немодальне, по одному на нотатку, зміни застосовуються під час набору;
  • вікно налаштувань — модальний діалог із OK / Cancel.

Головна вимога: жодне вікно не тримає посилання на інше вікно. Дані вікна беруть зі спільного AppState, перемальовуються за його сигналами, а відкриттям і закриттям керує один об'єкт — WindowManager.

Персоналізація

Константи, як і раніше, живуть тільки в app/config.py. До наявних додаються дві нові:

STUDENT_NAME = "Ivan Petrenko"                # ваше ім'я та прізвище транслітерацією
STUDENT_GROUP = "KI-31"                       # ваша група
DB_FILE = "workspace_ivan_petrenko.db"        # файл бази з практичних 3-5
APP_TITLE = "Notes Manager"                   # назва застосунку
CASCADE_STEP = 40                             # зсув кожного наступного вікна, пікселів
DEFAULT_PREVIEW_LENGTH = 30                   # символів тексту нотатки у списку

Заголовки вікон:

Вікно Заголовок
перше головне Notes Manager - Ivan Petrenko, KI-31
друге, третє, ... головне Notes Manager (2) - Ivan Petrenko, KI-31
вікно нотатки Note 7 - Notes Manager
вікно нотатки з незбереженими змінами Note 7* - Notes Manager
налаштування Preferences

Структура проєкту

Нові файли позначено <- нове; решта береться з практичної 7 без переписування з нуля:

notes_manager/
├── main.py                      <- створює storage, state, WindowManager
├── check_state.py               <- доповнюється перевірками налаштувань
├── workspace_ivan_petrenko.db
└── app/
    ├── __init__.py
    ├── config.py                <- дві нові константи
    ├── models.py
    ├── storage.py
    ├── state.py                 <- нові сигнали й налаштування
    └── ui/
        ├── __init__.py
        ├── window_manager.py        <- нове: реєстр відкритих вікон
        ├── main_window.py
        ├── note_list_panel.py
        ├── note_editor_panel.py
        ├── note_window.py           <- нове: немодальне вікно однієї нотатки
        └── preferences_dialog.py    <- нове: модальний діалог налаштувань

Схема головного вікна

Порівняно з практичною 7 змінюється небагато: у меню з'являється розділ вікон, у рядку стану — номер вікна.

+----------------------------------------------------------------------+
|  MainWindow                 Notes Manager - Ivan Petrenko, KI-31     |
+----------------------------------------------------------------------+
|  Note      Edit      Window      Help              <- menuBar()      |
+----------------------------------------------------------------------+
|  [New] [Save] [Delete] | [Open in new window]      <- QToolBar       |
+----------------------------------------------------------------------+
|                         |                                            |
|  +-------------------+  |  +--------------------------------------+  |
|  |                   |  |  |                                      |  |
|  |  note_list_panel  |  |  |         note_editor_panel            |  |
|  |                   |  |  |          (centralWidget)             |  |
|  +-------------------+  |  +--------------------------------------+  |
|                         |                                            |
+----------------------------------------------------------------------+
|  Ready                          [ Window: 1 ]   [ Notes: 12 ]        |
|                                                   <- statusBar()     |
+----------------------------------------------------------------------+

Схема вікна нотатки

+----------------------------------------------------+
|  NoteWindow            Note 7* - Notes Manager     |
+----------------------------------------------------+
|  Note 7                     [x] Pinned             |
|                              ^- pinned_box         |
|                                                    |
|  +----------------------------------------------+  |
|  |                                              |  |
|  |                  text_edit                   |  |
|  |                 (QTextEdit)                  |  |
|  |                                              |  |
|  +----------------------------------------------+  |
|                                                    |
|  Updated: 2026-09-01 14:30            [ Close ]    |
|   ^- updated_label                                 |
+----------------------------------------------------+

Вікно нотатки — це QWidget верхнього рівня (без батька), а не QDialog і не QMainWindow.

Схема діалогу налаштувань

+-------------------------------------------------+
|  PreferencesDialog               Preferences    |
+-------------------------------------------------+
|  Applies to every open window.                  |
|                                                 |
|  [x] Show pinned notes first                    |
|   ^- pinned_first_box                           |
|                                                 |
|  Preview length:  [ 30 ]                        |
|                     ^- preview_spin             |
|                                                 |
|                         [ OK ]  [ Cancel ]      |
|                          ^- QDialogButtonBox    |
+-------------------------------------------------+

Команди

Команда Клавіша Меню Що робить
New window Ctrl+Shift+N Window відкриває ще одне головне вікно з тими самими даними
Open in new window Ctrl+Return Note відкриває вікно вибраної нотатки; подвійне клацання по списку робить те саме
Close window Ctrl+W Window закриває поточне вікно, а не застосунок
Preferences... Ctrl+, Edit відкриває модальний діалог налаштувань
Quit Ctrl+Q Note закриває всі вікна через QApplication.closeAllWindows()

Команди з практичної 7 (New note, Save note, Delete note, Pin, Export, About) лишаються на місці й мають працювати в кожному головному вікні.


Знайшли помилку чи бажаєте додати інформацію, щоб покращити курс? Створіть issue на GitHub