Mac App StoreのTodo、Pyqt5 ModelViewアーキテクチャを使用して、シンプルなTODOアプリを構築する

ビューでデータを表示するためのModelViewアーキテクチャQT S MVCのようなインターフェイス

実行中のアプリを以下に示します.

Todo 4+

数年間、私はiPad、iPhone、MacBookproでこのアプリケーションを使用しました. それがiOSで完全に機能し続けている場合、それはmacosの進化に完全に従っていないようです.
インストールするのに問題はありません. しかし、iOSでは継続している間、MacOSのToodledoと同期することはもはや不可能です。同じ識別子は認識されていません.
したがって、それは私にとって不要になります…そして、Appigoの支援は私の要求に答えを提供するために急いでいないようです. 顧客の概念が毎日もう少しその価値を失うことに注意するのは常に不快です.

ピサd

このアップデート以来、私はすべてのリストを12の数で失いました、そして私は毎日プロの方法で働いています. 私は約200のスポットを永久に管理しています、このアップデートは試練の地上数ヶ月になりました ! リストに整理されたすべてのタスクは、単一のグローバルリストにグループ化されていることがわかりました. 確かにこのバグは、このソフトウェアのプロフェッショナルが優れていると言ってバージョンに渡すことではありません. 私は決して捕虜になることはありません. 今晩、電子メールで連絡したサポートの応答を待つか、この壮大なソフトウェアの古いバージョンを見つけるのは私にとってのみ残っています. それが新しいバージョンの若々しいBeugであり、有料プロ版に移行することを強制する戦略ではなく、以前のバージョンですでに取得した機能を見つけることを願っています. 情報のために、私の同期はDropboxで行われます

サレポイント、2011年12月13日

シンクロはニッケルになりました

同期する前に、ゆっくりと歩いた後、ひどく歩きました。. しかし、今ではiCloudで、それは私に完全に合っています.

いくつかの可能性のある改善点:ディスプレイ設定が増えます.
– ユーザーが使用するもののみを表示するには. たとえば、私はコンテキストやラベルを使用していません(いずれにしてもまだ)。. 日常のメモには「日付 /優先度 /リスト /タイプ」のみを持ち、めったに使用しないオプションを右クリックしたい
– 逆に、日付、優先順位、リストなどを選択するドロップダウンメニューよりもシンプルなPLSUディスプレイが必要です… 3つのリストしかない場合、3つのボタンが表示され、リストを選択できます。ドロップダウンメニューをクリックする代わりにワンクリックして、名前を見つけて、それをクリックします. (優先順位のために、特に私たちはTODOリストの非常に視覚的な描画から、あまり自然ではないオプションの名前の選択に行くことです.

これらは人間工学の詳細です. 私はTODOのシンプルさと効率が好きなので、さらにシンプルになるようにさらに構成できるようになりたいと思います.

プライバシーアプリ

開発者のAppigoは、その個人慣行とAppleへのデータの取り扱いに関する詳細を提供していません. 詳細については、開発のプライバシーポリシーを参照してください.

モデルビューアーキテクチャ
ビューにデータを表示するためのQTのMVCのようなインターフェイス

PYQT5を使用してより複雑なアプリケーションを構築し始めると、データと同期してウィジェットを保持する可能性があります. ウィジェットに保存されているデータ(e.g. Simple QlistWidget)はPythonから操作するために容易に利用できません – 変更には、アイテムを取得し、データを取得してから戻してから戻す必要があります. これのデフォルトの解決策は、Pythonに外部データ表現を保持し、EITHがデータとウィジェットの両方に複製するか、データからWiholeウィジェットを書き換えるだけで、. これはugいで迅速になり、データをいじるためだけに多くのホイロプレートをもたらすことができます.

ありがたいことに、QTにはこれに対するソリューションがあります – モデルビュー. ModelViewsは、単純なデータ構造から外部データベースまで、通常のモデルインターフェイスを使用してデータソースと対話する標準ディスプレイウィジェットの強力な代替品です。. これにより、データを好きな構造に保持できるようにしますが、ビューはプレゼンテーションと更新の世話をします。.

このチュートリアルでは、QTのModelViewアーキテクチャの重要な側面を紹介し、それを使用してPYQT5で簡単なデスクトップTODOアプリケーションを構築します.

モデルビューコントローラー

モデル – 参照 – コントローラー (MVC)は、アプリケーションを3つの相互接続されたパーツに分割する開発ユーザーインターフェイスのためのアーキテクチャパターンの使用です. これにより、データの内部表現が情報の提示方法とユーザーから受け入れられる方法を分離します.

MVCデザインPattennは3つの主要なコンポーネントをフェットします –

  • モデル アプリが動作しているデータ構造を保持します.
  • ビュー ユーザーに示されている情報の表現は、グラフィックまたはテーブルで. 同じデータモデルの複数のビューが許可されています.
  • コントロール ユーザーからの入力を受け入れ、モデルまたはビューのためにコマンドに変換します.

それはビューとコントローラーの区別を着陸させます。. QTは(OS経由)ユーザーからの入力イベントを受け入れ、これらをウィジェット(コントローラー)に委任して処理します. ただし、ウィジェットは現在の状態のプレゼンテーションをユーザーに処理し、ビューにまっすぐに配置します. ラインを描く場所に苦しむのではなく、qt-speakでビューとコントローラーが統合されています。.

重要なことに、間の区別 データ そして それがどのように提示されるか 保存されています.

モデルビュー

モデルは、データストアとViewControllerの間のインターフェイスとして機能します. モデルはデータ(またはそれへの参照)を保持し、このデータを標準化されたAPIを介して提示し、それを表示してからユーザーに消費して提示します. 複数のビューで同じデータを共有でき、まったく異なる方法で提示します.

標準のPythonリストや辞書など、モデルには「データストア」を使用できます。.g. sqlalchemy) – それはあなた次第です.

2つの部分は本質的に責任があります –

  1. お茶 モデル データ、またはそれへの参照を保存し、レコードの個別または範囲を返し、関連するメタデータまたは 画面 説明書.
  2. お茶 ビュー モデルからデータを要求し、ウィジェットに返されるものを表示します.

ドキュメントにはQTアーキテクチャの詳細な議論があります.

Pyinstallerを使用したパッケージングPython GUIアプリケーションの完全なガイド.

Pyinstallerを使用したパッケージPythonアプリケーション

[[割引.Discount_pc]]]次の[割引の%オフ.期間]] [割引.説明]]コード[割引.クーポンコード]]

購買力平価

[[country]]を取得する開発者[[割引.割引_pc]]]コード付きのすべての書籍とコースのオフ[割引.クーポンコード]]

シンプルなモデルビュー – TODOリスト

実際にモデルビューを使用する方法を示すために、デスクトップTODOリストの非常に簡単な実装をまとめます. これは、アイテムのリストのqlistView、新しいアイテムを入力するためのqlineedit、および完了したアイテムを追加、削除、またはマークするボタンのセットで構成されます.

UI

シンプルなUIは醜い外出QT作成者であり、MainWindowとして保存されました.ui . お茶 .UIファイルと他のすべての部品は以下にダウンロードできます.

QT作成者でシンプルなTODOアプリを設計します

QT作成者でシンプルなTODOアプリを設計します

実行中のアプリを以下に示します.

ランニングトッドギー(まだ機能しない)

ランニングトッドギー(まだ機能しない)

以下の表に示されているIDに与えられたインターフェイスで利用可能なウィジェット.

objeuch 親切 説明
Todview qlistview 現在のTODOのリスト
トドディット qlineedit 新しいTODOアイテムを作成するためのテキスト入力
addbutton qpushbutton 新しいtodoを作成し、それをTodosリストに追加します
DeleteButton qpushbutton 現在の選択されたTODOを削除して、TODOSリストから削除します
CompleteButton qpushbutton 完了したとおりに選択されたTODOをマークします

これらの識別子を使用して、後でアプリケーションロジックを接続します.

モデル

実装からサブクラス化してカスタムモデルを定義し、モデルに固有のパーツに集中できるようにします. QTは、リスト、ツリー、テーブルなど、さまざまなモデルベースを提供します(スプレッドシートに最適です).

この例では、結果をqlistviewに表示しています . これの一致するベースモデルはQabstractListModelです . モデルのアウトライン定義を以下に示します.

クラストドモデル(Qtcore.QabstractListModel):def __init __(self、 *args、todos = none、** kwargs):super(todomodel、self).__init __(*args、** kwargs)self.todos = todosまたは[] def data(self、index、role):if role == qt.DisplayRole:#データ構造については、以下を参照してください. ステータス、テキスト= self.Todos [インデックス.row()]] #TODOテキストのみを返します. return text def rowcount(self、index):return len(self.トドス) 

お茶 .TODOS変数は当社のデータストアであり、2つのメソッドrowCount()とdata()は標準モデルメソッドです。リストモデルには必要です. 以下で順番に説明します.

.トドスリスト

モデルのデータストアはです .Todos、単純なPythonリストでは、値のタプルをフォーマット[(bool、str)、(bool、str)、(bool、str)]に保存します。 したがって 特定のエントリの状態、およびstrはtodoのテキストです.

自分自身を初期化します.TODOSキーワード引数を介してリストが渡されない限り、スタートアップの空のリストにtodo.

自己.todos = todosまたは[]は自己を設定します.もしそうなら、提供されたTodosの価値にtodos トルーティ (私.e. 空のリスト、ブールのfalse、またはnone no None以外のもの)、それ以外の場合は空のリストに設定されます[] .

このモデルの挿入を作成するために、私たちは簡単にできます –

model = todomodel()#空のtodoリストを作成する 

または既存のリストに渡す –

todos = [(false、 'an item')、(false、 'Another Item')] Model = Todomodel(Todos) 

.rowcount()

お茶 .rowcount()メソッドは、現在のデータの行の数を取得するためにビューによってカレードされます. これは、ビューにデータストアをやり直すことができる最大インデックス(行Count-1)に必要です. 販売Pythonリストをデータストアとして使用する販売、これの返品値は単にリストのlen()です.

.データ ()

これはモデルの中核であり、ビューからデータのリクエストを処理し、適切な結果を返します. 2つのパラメーターインデックスとロールを受信します.

インデックスは、ビューが要求しているデータの位置/座標であり、2つの方法でアクセスできます .row()and .各次元に位置を与える列().

QlistViewの場合、列は常に0であり、無視できますが、スプレッドシートビューの2Dデータにこれを使用する必要があります.

役割は、を示すフラグです 親切 ビューが要求しているデータの. これは、 .data()メソッドは実際にはコアデータだけよりも多くの責任を負っています. また、スタイル情報、ツールチップ、ステータスバーなどのリクエストを処理します。. – データ自体が通知できる基本的に何でも.

QTの命名.displayroleは少し奇妙ですが、これは ビュー 「ディスプレイのためにデータをください」と尋ねています. 他にもあります 役割 スタイリングリクエストや「編集準備」形式のデータのリクエストに対してデータが受信できる.

役割 価値 説明
QT.画面 0 テキストの形で下される重要なデータ. (QSTRING)
QT.装飾ロール 1 アイコンの形の装飾としてレンダリングされるデータ. (qcolor、qicon、qpixmap)
QT.社説 2 編集者で編集するための正式なフォローのデータ. (QSTRING)
QT.Tooltiprole 3 アイテムのツールチップに表示されるデータ. (QSTRING)
QT.Statustiprole 4 ステータスバーに表示されるデータ. (QSTRING)
QT.whatshisrole 5 「これは何ですか?” ファッション. (QSTRING)
QT.サイズヒントール 13 ビューに提供されるアイテムのサイズのヒント. (Qsize)

利用可能な完全なリストについて 役割 QT itmdataroleドキュメントをご覧ください. TODOリストはQTのみを使用します.DisplayRoleとQT.装飾ロール .

基本的な実装

以下は、UIをロードして表示するために必要な基本的なスタブアプリケーションです. このベースにモデルコードとアプリケーションロジックを追加します.

pyqt5からsysをインポートqtcore、qtgui、qtwidgets、pyqt5からのuic.QTCOREインポートQT_CREATOR_FILE = "MainWindow.ui "ui_mainwindow、qtbaseclass = uic.loaduduype(qt_creator_file)クラスTodomodel(qtcore.QabstractListModel):def __init __(self、 *args、todos = none、** kwargs):super(todomodel、self).__init __(*args、** kwargs)self.todos = todosまたは[] def data(self、index、role):if role == qt.displayrole:status、text = self.Todos [インデックス.row()] return text def rowcount(self、index):return len(self.TODOS)クラスMainWindow(Qtwidgets.qmainwindow、ui_mainwindow):def __init __(self):qtwidgets.QumainWindow.__init __(self)ui_mainwindow.__init __(self)self.setupui(self)self.Model = todomodel()self.Todview.SetModel(self.モデル)app = qtwidgets.qapplication(sys.argv)window = mainWindow()ウィンドウ.show()app.exec_() 

Todomodelを以前のように定義し、MainWindowオブジェクトを初期化します. MainWindowの__init__では、TODOモデルのインスタンスを作成し、TODO_VIEWでこのモデルを設定します . このファイルをtodoとして保存します.pyとそれを実行します –

python3 todo.ペース 

まだ見えるものはあまりありませんが、QLISTVIEWとモデルは実際に機能しています – デフォルトデータを追加すると、リストに表示されます.

自己.Model = todomodel(todos = [(false、 'my first todo'))))) 

ハードコーディングされたトッドアイテムを示すqlistview

ハードコーディングされたトッドアイテムを示すqlistview

あなたはこのように手動でアイテムを追加し続けることができ、それらはQlistViewに順番に表示されます . 次に、アプリケーション内からITMを追加することを可能にします.

最初にaddという名前のmainwindowに新しいメソッドを作成します . これは私たちのコールバックで、新しいTODOとして入力から現在のテキストを追加することに注意してください. この方法をAddButtonに接続します.__init__ブロックの最後に押された信号.

クラスMainWindow(Qtwidgets.qmainwindow、ui_mainwindow):def __init __(self):qtwidgets.QumainWindow.__init __(self)ui_mainwindow.__init __(self)self.setupui(self)self.Model = todomodel()self.Todview.SetModel(self.モデル)#ボタンを接続します. 自己.addbutton.プレス.Connect(self.add)def add(self): "" qlineeditからテキストを取得して、TODOリストにアイテムを追加します .Todoeditとそこにそれをクリアします. "" "Text = self.トドディット.テキスト()の場合:#空の文字列を追加しないでください. #モデルを介してリストにアクセスします. 自己.モデル.トドス.append((false、text))#トリガーリフレッシュ. 自己.モデル.レイアウトチェンジ.emit()#入力自己を空にします.トドディット.settext( "") 

ADDブロックでは、ラインセルフに注意してください.モデル.レイアウトチェンジ.emit() . ここでは、モデル信号を発します .レイアウトされて、ビューにそれを知らせてください データが変更されました. これにより、ビューのエンティティのリフレッシュがトリガーされます. この行を省略した場合、TODOはまだ追加されますが、qlistViewは更新されません.

データだけが変更されているが、行/列の数が影響を受けていない場合は、 .代わりにdatachanged()信号. これはまた、ビュー全体のビューを再描画しないように、左上および右下のレンタルを使用してデータの変更された領域を定義します.

他のアクションを接続します

これで、ボタンの信号の残りの部分を接続して、パフォーマンスのためのヘルプを追加できます 消去 そして 完了 オペレーション. 以前のように__init__ブロックにボタン信号を追加します.

 自己.addbutton.プレス.Connect(self.追加)自己.DeleteButton.プレス.Connect(self.削除)self.CompleteButton.プレス.Connect(self.完了) 

次に、次のように新しい削除メソッドを定義します –

 def delete(self):indexes = self.Todview.selecteddindexes()indexes:#indexesは単一選択の単一項目のリストです. index = indexes [0]#アイテムを削除して更新. Del Self.モデル.Todos [インデックス.row()]自己.モデル.レイアウトチェンジ.emit()##選択をクリアします(長い間有効ではないため). 自己.Todview.clarselection() 

私たちは自己を使用します.Todview.selecteddindexesインデックスを取得するには(実際には単一選択モードのように単一のアイテムのリスト)、次に .row()モデルのTODOのリストへのインデックスとして. PythonのDelオペレーターを使用してインデックス付きアイテムを削除し、データの形状が変更されているため、レイアウトチェンジ付き信号をトリガーします.

Finalllyは、それが関連するアイテムが現在範囲外であるため(最後のアイテムを選択した場合)、アクティブな選択をクリアします。.

これをスマートにしてみて、代わりにリストの最後の項目を選択してみることができます

このような完全な方法 –

 def complete(self):indexes = self.Todview.selectredindexes()の場合:indexes:index = indexes [0] row = index.row()status、text = self.モデル.Todos [row] self.モデル.todos [row] =(true、text)# .Datachangedは左上と右下を右にします。これは単一の選択で等しい#. 自己.モデル.データチャンジ.Emit(index、index)#選択をクリアします(長い間有効でないため). 自己.Todview.clarselection() 

これは削除と同じインデックス作成を使用しますが、今回はモデルからアイテムを取得します .TODOSリスト、その後、ステータスをtrueに置き換えます .

私たちのデータは、変更できないPythonタプルとして保存されているため、このフェッチと再配置を行う必要があります.

ここで違う鍵となると. 標準のQTウィジェットは、データに直接変更を加えることであり、簡単にQTにhaasurdを変更することを通知する必要があります – ウィジェット状態の更新は自動的に処理されます.

QTを使用します.装飾ロール

今すぐアプリケーションを実行すると、両方の作業を追加して削除することがわかりますが、アイテムの完了が機能している間、ビューにはそれを示すことはありません. アイテムが完了したときに表示するインジケーターをビューを提供するには、モデルを更新する必要があります. 更新されたモデルを以下に示します.

ティック= qtgui.Qimage( 'ティック.png ')クラスTodomodel(qtcore.QabstractListModel):def __init __(self、 *args、todos = none、** kwargs):super(todomodel、self).__init __(*args、** kwargs)self.todos = todosまたは[] def data(self、index、role):if role == qt.displayrole:_、text = self.Todos [インデックス.row()] [textの場合はtextを返します== qt.装飾ロール:ステータス、_ = self.Todos [インデックス.row()]の場合:ステータス:return tick def rowcount(self、index):return len(self.トドス) 

ティックアイコンティックを使用していました.完全なアイテムを示すPNG。 . モデルでは、QTのハンドラーを実装しました.ステータスが真である行のティックアイコンを返す装飾ロール(完全に).

私が使用しているアイコンは、Pによって設定されたFugueから取られています.Yusukekamiyamane

Iアイコンのintostadあなたも色に戻すことができます、e.g. qtgui.Qcolor( ‘緑’)は、固体正方形として描画されます.

アプリを実行すると、アイテムを完全にマークできるようになりました.

トドスが完全にマークされました

トドスが完全にマークされました

永続的なデータストア

私たちのTodoアプリはうまく機能しますが、致命的な欠陥が1つあります。アプリケーションを閉じるとすぐにTODOを忘れてしまいます。悪いアイデア.

解決策は、永続的なデータストアのいくつかの外出を実装することです. 最も簡単なアプローチは、スタートアップでJSONまたはピクルスファイルからアイテムをロードし、変更を書き戻すシンプルなファイルストアです。.

これを行うには、2つの新しい方法を手に定義します . JSONファイル名データからのこれらのロードデータ.JSON(存在する場合、エラーがない場合は無視していない)自己.モデル.トドスと現在の自己を書いてください.モデル.それぞれ同じファイルにトドを出します.

 def load(self):try:with open( 'データ.json '、' r ')as f:self.モデル.todos = json.ロード(f)例外:パスdef save(self):with open( 'データ.json '、' w ')as f:data = json.ダンプ(自己.モデル.トドス、f) 

データの変更を維持するには、追加する必要があります .データを変更するメソッドの最後まで保存()ハンドラー、および .モデルが作成された後、__init__ブロックへのload()ハンドラー.

最終コードはこのように見えます –

importsysはpyqt5からjsonをインポートしますqtcore、qtgui、qtwidgets、pyqt5からのuic.QTCOREインポートQT_CREATOR_FILE = "MainWindow.ui "ui_mainwindow、qtbaseclass = uic.loadudusepe(qt_creator_file)tick = qtgui.Qimage( 'ティック.png ')クラスTodomodel(qtcore.QabstractListModel):def __init __(self、 *args、todos = none、** kwargs):super(todomodel、self).__init __(*args、** kwargs)self.todos = todosまたは[] def data(self、index、role):if role == qt.displayrole:_、text = self.Todos [インデックス.row()] [textの場合はtextを返します== qt.装飾ロール:ステータス、_ = self.Todos [インデックス.row()]の場合:ステータス:return tick def rowcount(self、index):return len(self.TODOS)クラスMainWindow(Qtwidgets.qmainwindow、ui_mainwindow):def __init __(self):super(mainwindow、self).__init __()self.setupui(self)self.Model = todomodel()self.load()self.Todview.SetModel(self.モデル)自己.addbutton.プレス.Connect(self.追加)自己.DeleteButton.プレス.Connect(self.削除)self.CompleteButton.プレス.Connect(self.complete)def add(self): "" "qlineeditからテキストを取得して、TODOリストにアイテムを追加します .Todoeditとそこにそれをクリアします. "" "Text = self.トドディット.テキスト()の場合:#空の文字列を追加しないでください. #モデルを介してリストにアクセスします. 自己.モデル.トドス.append((false、text))#トリガーリフレッシュ. 自己.モデル.レイアウトチェンジ.emit()#入力自己を空にします.トドディット.settext( "")self.save()def delete(self):indexes = self.Todview.selecteddindexes()indexes:#indexesは単一選択の単一項目のリストです. index = indexes [0]#アイテムを削除して更新. Del Self.モデル.Todos [インデックス.row()]自己.モデル.レイアウトチェンジ.emit()##選択をクリアします(長い間有効ではないため). 自己.Todview.Clarselection()Self.save()def complete(self):indexes = self.Todview.selectredindexes()の場合:indexes:index = indexes [0] row = index.row()status、text = self.モデル.Todos [row] self.モデル.todos [row] =(true、text)# .Datachangedは左上と右下を右にします。これは単一の選択で等しい#. 自己.モデル.データチャンジ.Emit(index、index)#選択をクリアします(長い間有効でないため). 自己.Todview.Clarselection()Self.save()def load(self):try:with open( 'データ.db '、' r ')as f:self.モデル.todos = json.ロード(f)例外:パスdef save(self):with open( 'データ.db '、' w ')as f:data = json.ダンプ(自己.モデル.Todos、f)app = qtwidgets.qapplication(sys.argv)window = mainWindow()ウィンドウ.show()app.exec_() 

アプリケーションのデータが大きくまたは複雑になる可能性がある場合、実際のデータベースを使用して保存することを可能にすることができます. この場合、モデルはインターフェイスをデータベースにラップし、データを表示するために直接照会します. l’llカバー今後のチュートリアルでこれを行う方法.

QLISTVIEWの別の興味深い例については、この例メディアプレーヤーアプリケーションを参照してください. QTビルディングQMediaplayListをデータストアとして使用し、コンテンツをQListViewに表示します .

BCRについて.CX:

BCR.CXは、ビジネスアウトソーシングプロセス(BPO)とビジネス環境アウトソーシング(BEO)の両方に特化したブラジルのテクノロジースタートアップであり、主に需要生成、カスタマーエクスペリエンス、コミュニケーション、ユーザーサポート、および満足度に焦点を当てた.

説明:

TODOアプリは、就業日中にエージェントのメモを保存するための迅速で安全でユーザーフレンドリーな方法として開発されました.

個々のチケットまたは顧客に基づいて、独自のタスクを作成および管理できるように.

トレイルを作成し、ワークフローをカスタマイズします

生産性が向上します! TODOアプリを使用すると、カスタマイズされたワークフローを作成して繰り返しプロセスを標準化できます. 今すぐ試して、あなたのTodosとDonesのようにあなたの進歩を制御し始めてください.

リソース:

  1. チケットごとにタスクを作成します
  2. 成果物をフォローアップするための進捗バー
  3. 標準化されたワークフローを作成して、生産性を向上させます.
  4. あなたの毎日のルーチンを維持するために、あなたのタスクリストを管理する.
  1. TODOとZENDESKの両方のSunshineをスタックして、アプリの機能を介したフルアクセスを取得する
  2. タスクの自動化を作成または編集することにより、生産性を向上させ、パーソナライズされたプリセットを保存します.