如何使用 PySide 真正分离逻辑和 UI

How to truly separate logic and UI using PySide

我试图将逻辑和 UI 分开。在下面的代码中,我有 UI 和逻辑 类。目标是用数据填充列表小部件 - 找到的 json 个文件的列表。在 UI 的第一个开始,它从 Data() 获取数据并用它填充列表。连接到 Data()create() 方法的按钮必须创建新文件并用新数据填充列表。我发现这样做的唯一方法是将主 window 传递给数据并进行刷新,我认为这与这种分离 UI 和逻辑的模型背道而驰。逻辑部分应该对 UI.

一无所知
from PySide2 import QtGui
from PySide2 import QtWidgets
import os
import json

HOME = os.path.expanduser("~")

class View(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()

        resolution = QtGui.QGuiApplication.primaryScreen().availableGeometry()
        self.setMinimumSize(resolution.width() * 0.25, resolution.height() * 0.3)
        self._central_widget = QtWidgets.QWidget()
        self.setCentralWidget(self._central_widget)


        self._list_widget_layout = QtWidgets.QVBoxLayout()
        self._buttons_layout = QtWidgets.QHBoxLayout()
        self._list_widget = QtWidgets.QListWidget()
        self._button = QtWidgets.QPushButton("Button")
        self._central_widget.setLayout(self._list_widget_layout)

        self._list_widget_layout.addWidget(self._list_widget)
        self._list_widget_layout.addLayout(self._buttons_layout)
        self._buttons_layout.addWidget(self._button)

        self._add_info = Data()
        # Connect
        self._button.clicked.connect(lambda: self._add_info.create(self))

        self.fill_list()

    def fill_list(self):
        self._list_widget.clear()
        for i in self._add_info.get_folder_content_by_extension(path=HOME, ext="json"):
            item = QtWidgets.QListWidgetItem()
            item.setText(i)
            self._list_widget.addItem(item)


class Data(object):

    def create(self, main_window):
        data_dict = {"A": "1", "B": "2", "C": "3" }
        self.save_json(path=os.path.join(HOME, "new_file.json"), save_dict=data_dict)
        main_window.fill_list()


    @classmethod
    def get_folder_content_by_extension(cls, path=None, ext=None):
        folder_content = list()

        for f in os.listdir(path):
            if f.endswith(".{}".format(ext)):
                folder_content.append(os.path.join(path, f))

        return folder_content

    @classmethod
    def save_json(cls, path, save_dict):
        with open(path, "w") as json_file:
            json.dump(save_dict, json_file, indent=4)

if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    w = View()
    w.show()
    app.exec_()

我注意到实际上我可以在连接到 self._add_info.create 之后将同一个按钮连接到 fill_list 方法。分开UI,逻辑就实现了。不知道这样对不对

from PySide2 import QtGui
from PySide2 import QtWidgets
import os
import json

HOME = os.path.expanduser("~")

class View(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()

        resolution = QtGui.QGuiApplication.primaryScreen().availableGeometry()
        self.setMinimumSize(resolution.width() * 0.25, resolution.height() * 0.3)
        self._central_widget = QtWidgets.QWidget()
        self.setCentralWidget(self._central_widget)


        self._list_widget_layout = QtWidgets.QVBoxLayout()
        self._buttons_layout = QtWidgets.QHBoxLayout()
        self._list_widget = QtWidgets.QListWidget()
        self._button = QtWidgets.QPushButton("Button")
        self._central_widget.setLayout(self._list_widget_layout)

        self._list_widget_layout.addWidget(self._list_widget)
        self._list_widget_layout.addLayout(self._buttons_layout)
        self._buttons_layout.addWidget(self._button)

        self._add_info = Data()
        # Connect
        self._button.clicked.connect(lambda: self._add_info.create())
        self._button.clicked.connect(self.fill_list)


        self.fill_list()

    def fill_list(self):
        self._list_widget.clear()
        for i in self._add_info.get_folder_content_by_extension(path=HOME, ext="json"):
            item = QtWidgets.QListWidgetItem()
            item.setText(i)
            self._list_widget.addItem(item)


class Data(object):

    def create(self):
        data_dict = {"A": "1", "B": "2", "C": "3" }
        self.save_json(path=os.path.join(HOME, "new_file.json"), save_dict=data_dict)


    @classmethod
    def get_folder_content_by_extension(cls, path=None, ext=None):
        folder_content = list()

        for f in os.listdir(path):
            if f.endswith(".{}".format(ext)):
                folder_content.append(os.path.join(path, f))

        return folder_content

    @classmethod
    def save_json(cls, path, save_dict):
        with open(path, "w") as json_file:
            json.dump(save_dict, json_file, indent=4)

if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    w = View()
    w.show()
    app.exec_()