C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

D&Dで入れ替わるリストビュー1

デモ用の社内アプリを社内で公開したので、ちょっと時間が
確保出来そうなので次のものに取り組みます。

リスト表示された項目をドラッグアンドドロップで、入れ替わるような
物が欲しいです。こんな感じです。
JavaScriptとHTMLを使ってドラッグアンドドロップで要素を並び替える方法 - WEBCAMP MEDIA
本当はもっと厄介なものを作りたいのですが、徐々に
改良していこうかと思っています。

fletにはリストビューは有るのですが、D&Dで入れ替わってくれるような
機能は無いです。・・・要は作れって事の様です。

公式のサンプルがこちらに大量にあります。
examples/python at main · flet-dev/examples · GitHub
有難いです。探すのは大変ですが、zipをダウンロードして
バンバン試せます。

ドラッグアンドドロップのサンプルは有るのですが、複雑すぎて・・・。
何となく試しつつやったら、こんな感じで文字の入れ替えが
出来ました。

# python using-flet
import flet as ft

def main(page: ft.Page):

    def drag_accept(e: ft.DragTargetAcceptEvent):
        src = e.page.get_control(e.src_id)
        target = e.page.get_control(e.target)

        target.content.value, src.content.content.value = src.content.content.value, target.content.value

        src.update()
        target.update()

    page.title = "Drag and drop test"

    page.add(
        ft.Draggable(
            group = "lists",
            content = ft.DragTarget(
                group = "lists",
                content = ft.Text(
                    'hoge',
                    size=50
                ),
                on_accept=drag_accept,
            )
        ),
        ft.Draggable(
            group = "lists",
            content = ft.DragTarget(
                group = "lists",
                content = ft.Text(
                    'piyo',
                    size=50
                ),
                on_accept=drag_accept,
            )
        )
    )

ft.app(target = main)

もーベタベタに書きました。分からなかったので。

実行するとこんな感じです。

わかんないですよね。


入れ替わりを許すためにはDraggableとDragTargetが一つの
コントロールになっている必要が有るのは分かっていたのですが、
どうやって書いたら良いのかが分かっていませんでした。

DraggableのcontentがDragTargetになっている必要が有るっぽく
逆は駄目だと思います。

もうちょっと汎用的なクラスにしてみました。

# python using-flet
import flet as ft

class DragAndDropItem(ft.UserControl):
    def __init__(self, group: str, value: str):
        super().__init__()
        self.group = group
        self.vaule = value

    def build(self):
        self.view = ft.Draggable(
            group = self.group,
            content = ft.DragTarget(
                group = self.group,
                content = ft.Text(
                    self.vaule,
                    size = 50
                ),
                on_accept = self._drag_accept,
            )
        )
        return self.view

    def _drag_accept(self, e: ft.DragTargetAcceptEvent):
        src = e.page.get_control(e.src_id)
        target = e.page.get_control(e.target)

        target.content.value, src.content.content.value = src.content.content.value, target.content.value

        src.update()
        target.update()


def main(page: ft.Page):

    page.title = "Drag and drop test"

    groupName = "test"
    textLst = [
        "hoge",
        "piyo",
        "fuga",
        "poyo",
    ]

    [page.add(DragAndDropItem(groupName, t)) for t in textLst]

ft.app(target = main)

動作はこんな感じです。


分かってます、動画で見せる程でも無い事を。

ドラッグ中の派手な文字は、何もしていなくても表示してくれます。
便利です。(カスタマイズも可能です)

リストビューでは無いのですが、それっぽく表示出来ているから
良いでしょ?