WxPythonを使用してノードインターフェイスを作成する例。 パート3:機能の追加とキーボード処理の継続

短いシリーズの記事では、WxPythonを使用して、ユーザーインターフェイスを開発するという非常に具体的なタスクを解決する方法と、このソリューションをユニバーサルにする方法について説明します。 このチュートリアルは、すでにこのライブラリの研究を始めており、最も単純な例よりも複雑で全体的なものを見たい人向けに設計されています(ただし、比較的単純なものから始まります)。

最後の部分では、マウスイベントの処理を実装しました。次に、別の機能を追加し、キーボードからのイベントの処理を実装します。

パート1:描画の学習
パート2:マウスイベントの処理
パート3:機能の追加とキーボード処理の継続
パート4:ドラッグアンドドロップの実装
パート5:ノードの接続

誰も気にせず、猫の下で歓迎…


7.オブジェクトを選択する


前回、ノードを移動する方法を学習しました。今度は、ノードだけでなく、キャンバス上のオブジェクトを削除する方法を学習します。 削除の場合は、まず削除するものを指定する必要があります。 オブジェクトを選択するので、削除ではなく選択から始めます。
誰もがハイライトするために通常はシングルクリックを使用しますが、私が知る限り、wxPythonには特別なシングルクリックイベントがないため、それを自分で追跡します。 これを最も簡単な方法で行います。ユーザーがマウスの左ボタンをクリックして同じピクセルの上で離すと、これがクリックになります。 これを行うには、ユーザーがボタンをクリックした場所を記憶する必要があり(「self._lastLeftDownPos」に保存します)、リリースされたら、選択したオブジェクトを比較して保存します。
def OnMouseLeftUp(self, evt): #Selection if (self._lastLeftDownPos and self._lastLeftDownPos[0] == evt.GetPosition()[0] and self._lastLeftDownPos[1] == evt.GetPosition()[1] and self._objectUnderCursor and self._objectUnderCursor.selectable): self._selectedObject = self._objectUnderCursor self.Render() 

さて、ユーザーがそこで強調表示したものを見るために、キャンバスレンダリングコードで、次のフラグメントを追加します。
  if self._selectedObject: gc.PushState() self._selectedObject.RenderSelection(gc) gc.PopState() 

それだけですか? すべてではありませんが、注意深い読者は、オブジェクトが選択可能かどうかを確認し、選択されたすべてのオブジェクト上にある新しいRenderSelectionメソッドを呼び出したことに気付きました。 そのため、動きのイメージと似顔絵に、選択可能なすべてのオブジェクトが継承される新しい基本クラスを追加します。
 class SelectableObject(CanvasObject): def __init__(self, **kwargs): super(SelectableObject, self).__init__(**kwargs) self.selectable = True def RenderSelection(self, gc): """ RenderHighlighting method should draw an object with a selection border around it. """ raise NotImplementedError() 

ちなみに、基本クラスはより大きく複雑になっているため、デザイナーは好きなだけ多くのパラメーターを取得し、文字列“ super(SelectableObject、self).__ init __(* * kwargs)。」
次のコードをノードに追加するだけです。
  def RenderSelection(self, gc): gc.SetBrush(wx.Brush('#888888', wx.TRANSPARENT)) gc.SetPen(wx.Pen('#CC0000', 3, wx.DOT)) gc.DrawRectangle(self.position[0]-2, self.position[1]-2, self.boundingBoxDimensions[0]+4, self.boundingBoxDimensions[1]+4) 

オブジェクトの周囲に選択範囲をレンダリングします。ノードのいずれかをクリックすると、そのような結果を確認できます。

いつものように、現在のコードはGitHubの対応するコミットで見つけることができます。

8.オブジェクトの削除


そこで、オブジェクトを削除することにしました。 削除するには、ユーザーが[削除]ボタンをクリックしたタイミングを追跡し、削除されたアイテムを実際に削除する必要があります。
まず、キーボードボタンをクリックするためのイベントハンドラが必要です。これは次のように登録します。
  self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress) 

そして、ハンドラーは次のコードを実行します。
  def OnKeyPress(self, evt): if evt.GetKeyCode() == wx.WXK_DELETE: if self._selectedObject and self._selectedObject.deletable: self._selectedObject.Delete() if self._selectedObject in self._canvasObjects: self._canvasObjects.remove(self._selectedObject) self._selectedObject = None else: evt.Skip() #Update object under cursor pos = self.CalcUnscrolledPosition(evt.GetPosition()).Get() self._objectUnderCursor = self.FindObjectUnderPoint(pos) self.Render() 

ここで、wx.WXK_DELETEコードでボタンを押すイベントが発生した場合、オブジェクトが選択されているか、削除されているかを確認します。 ある場合は、(Deleteを呼び出すことによって)休息し、キャンバス上のリストからオブジェクトを削除する時間であることを美しく通知します。 evt.Skip()は、他の場所で登録されたこのイベントに対して他のハンドラーを呼び出すようシステムに指示します。

今、すでに伝統的に、削除されたオブジェクトの基本クラスを追加することが残っています:
 class DeletableObject(CanvasObject): def __init__(self, **kwargs): super(DeletableObject, self).__init__(**kwargs) self.deletable = True def Delete(self): """ Delete method is called when an object is deleted from a canvas. """ raise NotImplementedError() 

また、キャンバスからオブジェクトを削除して楽しむことができます。 オブジェクトを追加するのは次の部分だけなので、真実はそれほど長くありません:)
現在のバージョンのコードは、 GitHubのこのコミットに含まれています

PS:誤字については個人で書いてください。

Source: https://habr.com/ru/post/J201608/


All Articles