PyQtでMVCパターンを設計しようとしています。すべてのプログラムを3つの部分に分割したいと思います。
SignalsToSlots
を使用したQtアプリ自体。これは最適ですか? PyQt開発での使用にはどのスキームが推奨されますか?
最初にすべきことの1つは、Qt4デザイナーを使用してGUIを設計し、pyuic4を使用してpython GUIを生成することです。これがビューになります。これらを編集しないでくださいpythonファイルは手動で作成します。常にデザイナーを使用して変更を加えます。これにより、ビューがモデルやコントロールから分離されます。
制御要素には、QMainWindowなどの基本GUIウィジェットから継承する中央クラスを作成します。このオブジェクトは、生成したビューオブジェクトであるメンバーUIをcontainします。
これが チュートリアル の例です
UPDATE 2013:これはPyQtとMVCモデルに関する最近のチュートリアルです PyQt MVCチュートリアルシリーズ
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では、アクセスを一元化することも重要です。たとえば、ユーザーは画面上でタイトルをダブルクリックするか、タイトルフィールドの横にある[編集]をクリックしてタイトルを変更できますbothこれらのインターフェイスのうち、変更には同じ方法を使用する必要があります。そしてこれは、それぞれがmovie.update_title(title)を呼び出すという意味ではありません。つまり、両方の信号がコントローラーで同じ方法を使用する必要があります。
ビューとコントローラーの間のすべての関係をできるだけ多く1にするようにしてください。つまり、GUIで何かを変更する方法は5つあり、コントローラーにはこれを処理するメソッドが1つあります。スロットにすべての互換性がない場合は、メソッドごとにメソッドを作成してから、1つのメソッドを呼び出します。 5つのビュースタイルで問題を5回解決した場合、ビューをコントロールから分離する理由は実際にはありません。また、コントローラーで何かを行う方法が1つしかないため、コントロールとモデルの間に1対1の優れた関係があります。
モデルをQtから完全に分離する限り、それは実際には必要ではなく、実際にあなたの生活を困難にする可能性があります。モデルでQStringsのようなものを使用すると便利です。別のアプリケーションで、Guiのオーバーヘッドを必要とせず、モデルにQtCoreのみをインポートしたい場合。うまくいけば、これが役立ちます!
はい、PyQtはモデル/ビューの概念を使用しています(公式には「コントローラー」部分はありません)が、PyQtでの意味が多少歪んでいる可能性があります。
2つの部分があります:
QAbstractItemModel
、QAbstractTableModel
、QAbstractListModel
など)からサブクラス化されたモデル。これらのモデルは、データソース(ファイル、データベース)と直接通信することも、以前に作成された独自のPyQtに依存しないモデルをプロキシすることもできます。QTreeView
、QTableView
など)。 QComboBox
のようないくつかのより単純なコントロールでさえ、PyQtモデルのビューとして機能することができます。シグナルなどに反応するアプリケーションの他のすべての部分は、「コントローラー」と見なされる場合があります。
PyQtは、QStringListModel
、QStandardItemModel
など、モデルの単純な機能のみが必要な場合にサブクラス化または直接使用できる、事前定義された「ユニバーサル」モデルのセットも提供します。モデルもあります。 QSqlTableModel
のようにデータベースと直接通信できます。
QtアーキテクチャがModel-Viewデザインをアプリケーションに提供する方法に関する公式の詳細なガイドへのリンクは次のとおりです。
http://doc.qt.io/qt-5/model-view-programming.html
Qtでは、ビューとコントローラーが組み合わされているため、Model-Viewフレームワークを使用してアプリを設計できます。
モデルはデータソースと通信し、アーキテクチャ内の他のコンポーネントにインターフェイスを提供します。通信の性質は、データソースのタイプとモデルの実装方法によって異なります。ビューはモデルからモデルインデックスを取得します。これらはデータ項目への参照です。モデルインデックスをモデルに提供することにより、ビューはデータソースからデータのアイテムを取得できます。標準ビューでは、デリゲートはデータのアイテムをレンダリングします。アイテムが編集されると、デリゲートはモデルインデックスを使用してモデルと直接通信します。
.。
モデル、ビュー、およびデリゲートは、シグナルとスロットを使用して相互に通信します