7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Tkinterでデスクトップマスコット的なものを作る。

Last updated at Posted at 2021-11-10

Tkinterだって色々できるもん。

Tkinterは難しい、色々できないなどでQtとかKivyとかを使おうみたいな流れがあったりWeb系の方が楽だーみたいな。そういうのありますよね、わたしもそういう流れを一通り体験したような気がします。(遠い目)

個人的には現在HTMLに匹敵するほどのことをTkinterで出来るようになってWebアプリをTkinterで作り直そうかみたいな感じになっていたりしてコツさえ分かればTkinterってのはとてもパワフルだし何しろ組み込まれているし動作軽いし、いいことばかり。

そんなところを一人でも多くの人に伝えられたらいいなと思い何かできないかとコードを起こしてみました。

デスクトップマスコット的な

Pythonを学習しているという方はよく目にしますが目標みたいなものが思いつかずなぞって「ふーん(?)」という感じにフェードアウトしそうな危うさなんてものを感じます。

何かに使えそうな面白そうなものはないかなーと考えてデスクトップマスコットだとかデスクトップウィジットとかのひな型に使えそうなもの。用意してみました。

前提

  • Windowsのみ

機種依存の機能を利用しているのでWindowsのみの対応となります。

コード

import tkinter as tk

class Mascot:

    """
     events
    """
    # These events handle dragging the window.
    def mouseDown(self, e):
        if e.num == 1:
            self.origin = (e.x, e.y)
            self.isMouseDown = True

    def mouseRelease(self, e):
        self.isMouseDown = False

    def mouseMove(self, e):
        if self.isMouseDown:
            buf = self.root.geometry().split("+")
            self.setPos(e.x - self.origin[0] + int(buf[1]),
                        e.y - self.origin[1] + int(buf[2]),
                        )

    # The application is terminated by pressing the "ESC" key.
    def keyReleease(self, e):
        if e.keycode == 27:
            self.root.destroy()

    """
     set geometry, Position
    """
    def setPos(self, x, y):
        self.root.geometry("+%s+%s" % (x, y))

    """
     load image, and drawing to canvas
    """
    def dispImage(self, path):
        self.canvas.delete("all")
        self.image = tk.PhotoImage(file=path)
        self.canvas.create_image(0, 0, image=self.image, anchor="nw")

    """
     create main window
    """
    def screenInit(self):
        # Set window size
        self.root.geometry("100x100")

        # Create canvas and drawing image
        self.canvas = tk.Canvas(self.root, bd=0, highlightthickness=0, bg="#003300")
        self.canvas.pack(fill="both")
        self.dispImage("res/python.png")

        """
         Various settings
        """
        # Transparency setting
        self.root.wm_attributes("-transparentcolor", self.canvas["bg"])

        # Disable window decoration
        self.root.overrideredirect(True)

        # Fix the screen to the front
        self.root.attributes("-topmost", True)

        """
         Bind events
        """
        self.canvas.bind("<Button>", self.mouseDown)
        self.canvas.bind("<ButtonRelease>", self.mouseRelease)
        self.canvas.bind("<Motion>", self.mouseMove)
        self.root.bind_all("<KeyRelease>", self.keyReleease)


    def __init__(self):
        self.origin = (0, 0)
        self.isMouseDown = False

        self.root = tk.Tk()
        self.screenInit()
        self.root.mainloop()

if __name__ == "__main__":
    m = Mascot()

画像

画像はpng形式で端がアンチエイリアスの掛かっていないものにしましょう。

python logo

こんなのをでっち上げてみました。

今回は画像を一つだけ使っていますが、複数の画像を読み込んでおいて場合によって切り替えるなんてのも当然できると思います(ハズです(汗))

動作イメージ

running desktop mascot

最前面に鎮座して、マウスでドラッグできます。
今回は機能的にそれだけです。
ESCキーを押すと終了します。

コードの解説。

  • ウィンドウのデコレーションを消す
  • ウィンドウを透過設定
  • ウィンドウを最前面に表示

これらがある以外は普通のTkinterを使ったアプリと変わりはありません。
そのあたりはscreenInitの中の3行で設定しています。

        """
         Various settings
        """
        # Transparency setting
        self.root.wm_attributes("-transparentcolor", self.canvas["bg"])

        # Disable window decoration
        self.root.overrideredirect(True)

        # Fix the screen to the front
        self.root.attributes("-topmost", True)
  • メニューバーがないので動かせない

ということになるので画像をドラッグできるようにするのも大切なところかもしれません。

        """
         Bind events
        """
        self.canvas.bind("<Button>", self.mouseDown)
        self.canvas.bind("<ButtonRelease>", self.mouseRelease)
        self.canvas.bind("<Motion>", self.mouseMove)
        self.root.bind_all("<KeyRelease>", self.keyReleease)

イベントを登録して

    """
     events
    """
    # These events handle dragging the window.
    def mouseDown(self, e):
        if e.num == 1:
            self.origin = (e.x, e.y)
            self.isMouseDown = True

    def mouseRelease(self, e):
        self.isMouseDown = False

    def mouseMove(self, e):
        if self.isMouseDown:
            buf = self.root.geometry().split("+")
            self.setPos(e.x - self.origin[0] + int(buf[1]),
                        e.y - self.origin[1] + int(buf[2]),
                        )

    # The application is terminated by pressing the "ESC" key.
    def keyReleease(self, e):
        if e.keycode == 27:
            self.root.destroy()

中身を実装しました。

一見難しそうに見えたりもするのかもしれませんがやってることはとても簡単です。

mouseDown の中では e.num (押されたマウスボタンの番号)が1として左クリックのみの処理を書いてあります。
右クリックされた場合とかをここに追加してゆけば様々な機能が追加できそうです。

次なる目標

現在はマウスでPythonのロゴを動かせるだけですのでここに何かしらの機能を追加してゆこうと思っています。

7
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?