Архитектура PyQt Model/View в Python — как работает

В этом руководстве вы узнаете, как работает шаблон PyQt Model/View в Python и его преимущества.

Знакомство с шаблоном PyQt «Model/View»

Model-View-Controller или MVC — это программный шаблон для разработки пользовательских интерфейсов(UI). Шаблон MVC разделяет UI(views), данные(models) и логику приложения(controllers):

Пример шаблона MVC

  • Модели представляют данные приложения или содержат логику для получения данных из базы данных.
  • Представления отвечают за представление моделей через пользовательский интерфейс.
  • Контроллеры обрабатывают вводимые пользователем данные, работают с моделями и выбирают представления для отображения данных.

Целью MVC является разделение задач между моделями, представлениями и контроллерами.

MVC позволяет легко добавлять или изменять views без изменения базовых моделей. Кроме того, MVC позволяет писать модульные тесты, нацеленные на модель и контроллер, без вовлечения пользовательского интерфейса.

Еще одним преимуществом MVC является то, что модель может иметь несколько представлений. И все эти представления могут автоматически обновляться на основе одной и той же модели.

PyQt использует вариант шаблона MVC, объединяя view и controller MVC в view, что приводит к архитектуре Model/View.

Архитектура «Model/View» позволяет PyQt свести взаимозависимость компонентов к минимуму и улучшить возможность повторного использования.

На следующем рисунке показан шаблон PyQt Model/View:

Пример шаблона PyQt ModelView

В архитектуре Model/View вид обрабатывает рендеринг данных через делегата. У делегата есть две основные обязанности:

  • Отображает данные.
  • Взаимодействует с моделью при редактировании данных.

Модели, виды и делегаты взаимодействуют друг с другом посредством сигналов и слотов.

PyQt предоставляет несколько стандартных виджетов Model/View:

  • QListView – отображает список элементов
  • QTableView – отображает таблицу элементов.
  • QTreeView – отображает иерархические данные.

Помимо этих виджетов, виджет QComboBox также поддерживает шаблон Model/View.

Кроме того, PyQt имеет ряд базовых классов моделей, таких как QAbstractListModel, QAbstractTableModel и QStandardItemModel.

Пример Model/View PyQt

Для иллюстрации Model/View PyQt рассмотрим простой пример:

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QComboBox, QListView
from PyQt6.QtCore import Qt, QStringListModel


class MainWindow(QWidget):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setGeometry(100, 100, 400, 200)
        self.setWindowTitle('PyQt Model/View')

        layout = QVBoxLayout()
        self.setLayout(layout)
        
        model = QStringListModel()
        model.setStringList(['Apple','Banana','Orange'])
        
        self.list_view = QListView()
        self.list_view.setModel(model)
        
        self.combo_box = QComboBox()
        self.combo_box.setModel(model)
        
        layout.addWidget(self.combo_box) 
        layout.addWidget(self.list_view)
                       
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec())

Как это работает.

В этом примере у нас есть два виджета: combobox и list view. Оба эти виджета используют одну и ту же модель, которая является экземпляром QStringListModel:

Иллюстрация Model/View PyQt

Если вы измените элемент из одного виджета, другой виджет автоматически обновит изменения. Другими словами, вам не нужно писать код, чтобы синхронизировать все виджеты, использующие одну и ту же модель:

  • Сначала создайте новый экземпляр класса QStringListModel и задайте список строк:
model = QStringListModel()
model.setStringList(['Apple','Banana','Orange'])
  • Во-вторых, создайте виджет QListView и установите для него следующую модель:
self.list_view = QListView()
self.list_view.setModel(model)
  • В-третьих, создайте виджет QComboBox и установите для него ту же модель, что и для виджета QListView:
self.combo_box = QComboBox()
self.combo_box.setModel(model)
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *