如何使用 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_()
我试图将逻辑和 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_()