Как правильно перезагрузить виджет после смены модели? - PullRequest
0 голосов
/ 11 июля 2020

Я создаю небольшое приложение PyQt5 и хочу следовать идеям гексагональной архитектуры и разработки на основе домена . Эти примеры относятся к golang и java, но я лучше смотрю на отображаемые принципы.

В моем примере приложения у меня есть объекты домена Книга и Книжная полка , и я могу добавлять / удалять / переупорядочивать книги на полке и с полки. В части приложения PyQt5 я хочу отобразить книжную полку как QGroupBox, содержащую несколько пользовательских QWidget s, каждая из которых представляет одну книгу. QGroupBox заменяется QVBoxLayout. Ради аргумента, на данный момент это могут быть простые QLabel s.

Вопрос: Как мне правильно обновить QGroupBox, отображая Книжную полку в PyQt? Примечание. В DDD и гексагональной архитектуре домен полностью не зависит от пользовательского интерфейса. Он может использовать события домена, но он не должен реализовывать / импортировать что-либо из PyQt, поскольку домену совершенно не важно, как он используется?

Подзапросы:

  1. PyQt использует для связи механизм сигналов и слотов. Однако на этот раз сигнал будет исходить из домена, и поэтому я не могу использовать типичный подход QObject для запуска пользовательских сигналов. Могу ли я создать прослушиватель домена, который переводит это в сигнал, или как лучше всего с этим справиться?
  2. Предполагая, что я получаю уведомление о событии в PyQt, как лучше всего перезагрузить содержимое виджета в покажите, как изменилась книжная полка? Я вижу три возможности:
    • замена QGroupBox совершенно новым QGroupBox и уничтожение старого.
    • удаление / уничтожение всех QLabel, представляющих книги, и вставка новых .
    • сохранение меток в макете / групповом поле и изменение только тех, которые были изменены.
  3. В зависимости от решения, выбранного для 2., как это будет выглядеть в коде фрагмент? Я уже нашел несколько решений по удалению виджетов из других виджетов / макетов, но каждое решение утверждает, что другие неверны. В основном были описаны два метода: использование deleteLater() http://josbalcaen.com/maya-python-pyqt-delete-all-widgets-in-a-layout/ и использование setParent(None) Очистить все виджеты в макете в pyqt

EDIT (добавленный пример кода): Вот небольшой пример кода для доменной части. Эта часть НЕ должна изменяться:

class Book:
    def __init__(self, title):
        self._title = title

    @property
    def title(self):
        return self._title


class Bookshelf:
    def __init__(self):
        self._books = []
        self._event_listeners = []

    @property
    def books(self):
        return self._books

    # for simplicity, this only appends books to the end
    def insert_book(self, book):
        self._books.append(book)
        self._shelf_updated()

    def take_book(self, book):
        self._books.remove(book)
        self._shelf_updated()

    def _shelf_updated(self):
        for listener in self._event_listeners:
            listener.bookshelf_updated()

    def register_event_listener(self, listener):
        self._event_listeners.append(listener)

    def remove_event_listener(self, listener):
        self._event_listeners.remove(listener)

Очевидно, что в этом примере что-то должно реагировать на bookshelf_updated().

...