我正在尝试使用PyQt设计MVC模式。 我想将所有程序分成3个部分:
SignalsToSlots
将信号与控制器连接。这是最佳的吗?建议在PyQt开发中使用什么方案?
答案 0 :(得分:42)
你应该做的第一件事就是使用Qt4设计师来设计你的gui并使用pyuic4来生成你的python GUI。这将是您的观点,您永远不要手动编辑这些python文件。始终使用设计师进行更改,这可确保您的View与您的模型和控件分开。
对于control元素,创建一个继承自基本gui小部件的中央类,例如QMainWindow。然后,此对象包含成员ui,它是您刚刚生成的视图对象。
的示例2013年更新:这是关于PyQt和MVC模型的最新教程 PyQt MVC Tutorial Series
import sys
from PyQt4 import QtCore, QtGui
from edytor import Ui_notepad
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_notepad()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
上例中的关键点是控制器包含ui并且不直接继承它。控制器将负责管理gui的信号槽连接,并为您的数据模型提供接口。
为了描述我们需要一个示例的模型部分,我们假设您的项目是创建一个电影收藏数据库。该模型将包括表示单个电影的内部对象,以及表示电影列表的对象。您可以控制从视图中输入的数据并捕获信号,然后在要求模型更新之前验证它们。那部分是至关重要的,如果可能的话,控制器不应该直接访问模型,它应该要求模型自己访问。
以下是此次互动的一个小例子(未经测试,可能是一些拼写错误):
class Movie():
def __init__(self,title=None,year=None,genre=None):
self.title=title
self.year=year
self.genre=genre
def update(self,title=None,year=None,genre=None):
self.title=title
self.year=year
self.genre=genre
def to_xml(self,title=None,date=None,genre=None):
pass #not implementing this for an example!
#when the controller tries to update it should use update function
movie1.update("Manos Hands Of Fate",1966,"Awesome")
#don't set by direct access, your controller shouldn't get that deep
movie1.title="Bad Idea" #do not want!
在MVC中集中访问也很重要,比如说用户可以通过在屏幕上双击来更改标题,或者点击标题字段旁边的编辑,这两个界面应该最终使用相同的方法进行更改。而且我并不是说每个人都会调用movie.update_title(标题)。我的意思是两个信号应该在控制器中使用相同的方法。
尝试尽可能多地将View和控制器之间的所有关系设置为1.意思是,你有5种方法可以在gui中改变某些东西,在控制器中有1个方法来处理这个问题。如果插槽不是所有兼容的,那么为每个方法创建方法,然后调用单个方法。如果您针对5种视图样式解决了5次问题,那么确实没有并且有理由将视图与控件分开。此外,由于您现在只有一种方法可以在控制器中执行某些操作,因此您可以在控件和模型之间建立良好的1对1关系。
就你的模型与Qt完全分离而言,这并不是真正必要的,实际上可能会让你的生活更加艰难。在你的模型中使用像QStrings这样的东西可能很方便,如果在另一个应用程序中你不想要Gui的开销,但是希望模型只导入QtCore。希望这有帮助!
答案 1 :(得分:6)
是的,PyQt使用模型/视图概念(官方没有“控制器”部分),但可能你有一些扭曲的图片在PyQt中意味着什么。
分为两部分:
QAbstractItemModel
,QAbstractTableModel
,QAbstractListModel
等创建的子类。这些模型可以直接与您的数据源(文件,数据库)进行通信,也可以代理您之前编写的PyQt无关模型。QTreeView
,QTableView
等)。甚至一些更简单的控件,如QComboBox
也可以作为PyQt模型的视图。您应用程序的所有其他部分(对信号做出反应等)可能被视为“控制器”。
PyQt还提供了一组预定义的“通用”模型,如果您只需要模型中的简单功能,可以进行子类化或直接使用,如QStringListModel
,QStandardItemModel
等。还有可以直接与数据库通信的模型,如QSqlTableModel
。
答案 2 :(得分:4)
以下链接指向Qt架构如何为应用程序提供模型 - 视图设计的官方详细指南
http://doc.qt.io/qt-5/model-view-programming.html
在Qt中,视图和控制器相结合,因此可以使用Model-View框架设计应用程序。
模型与数据源通信,提供接口 对于架构中的其他组件。的本质 通信取决于数据源的类型和方式 模型实施。视图从模型中获取模型索引; 这些是对数据项的引用。通过提供模型索引 在模型中,视图可以从数据源中检索数据项。 在标准视图中,委托呈现数据项。当一个项目 编辑后,委托直接使用与模型进行通信 模型索引。
...
模型,视图和委托使用信号和插槽相互通信