【Python】tkinterdnd2でドラッグ&ドロップをすると禁止マークが出てしまうときの対処
こんにちは、個人事業OguLinks代表の小倉(@jun_ogulinks)です。
PythonでGUI開発するときにtkinterを使っている方は多いと思いますが、ユーザビリティを考慮してドラッグアンドドロップ(DnD)ができると良いですよね?
tkinterでDnDを実装するにはtkinterdnd2を使うと簡単です。
今回は、tkinterdnd2が正しくインストールされているにも関わらず、禁止マークが出てドラッグアンドドロップができないという問題に出くわしたので、解決した方法について解説します。
Pythonでドラッグアンドドロップ(DnD)をしたいならtkinterdnd2
まず初めに、tkinterでのDnD実装について情報を整理しておきましょう。
DnDが使えるのと使えないのとではアプリケーションの使い勝手に天と地と程の差が出ます。
まあ、それは言い過ぎかもしれませんが、やはり使えた方が便利であることは間違いないのではないでしょうか。
PythonのGUI開発に使われるものとしてはtkinterやPyQtなどが有名です。
特にtkinterは標準パッケージとして最初から入っていますので、インストールの手間もなくすぐ使えるのが魅力ですね。
また、昔からあるものなので、ネット上に情報が多いというのも使うときのメリットになります。
ライセンス的にも無料でソースコードを晒さずにアプリケーション開発ができますので、商用利用しやすいというのもあります。
さて、tkinterはデフォルトではDnDの機能がありません。
そこでtkinterにDnD機能を追加するわけですが、その方法はいくつかあります。
以下はtkinterでDnDを行える方法としてネット上で紹介されているものです。
- tkinterdnd2
- dnd.py
- ctypesによるもの
ネット上の情報としては、圧倒的にtkinterndnd2が多いように思います。
dnd.py はtkinterに含まれるファイルです。
実は \Anaconda3\Lib\tkinter のフォルダ内にこのファイルが存在していて、デモを動かすことが可能です。
dnd.pyについては石川満律さんという方がこちらの記事で紹介しています。
Python tkinter GUI プログラミング ドラッグ・アンド・ドロップ
ただし、このdnd.pyの欠点はアプリケーション内のDnDしかできないという点です。
つまり、Windowsのエクスプローラー(Macならファインダー)からファイル等をアプリケーション内にDnDするといったことができないようです。
このファイルを開くと最初にこのような文章が書いてあります。
This is very preliminary. I currently only support dnd within one
application, between different windows (or within the same window).
これは非常に予備的なものです。 現在、私は1つのアプリケーションの中でしかdndをサポートしていません。アプリケーション内、異なるウィンドウ間(または同じウィンドウ内)でのみサポートしています(DeepL翻訳まま)。
そのため、用途が限定されます。
使用時には注意が必要でしょう。
その他としてはPythonのctypesパッケージを利用したものがあります。
この手のタイプはWindows APIを使ってDnDを実現させているということらしいので、Windowsでしか使えないというデメリットがあります。
その中でもPyPI経由で簡単にインストールできるwindndというものがあります。
こちらについては、tkinterdnd2とwindndの両方を紹介している、みえき256(mieki256)さんの記事が分かりやすかったです。
Windowsでの開発しかしない人にとっては選択肢の一つになりそうですね。
ただ、ここまでの情報でわかる通り、クロスプラットフォームで汎用性が高く、実装しやすいものとなるとtkinterdnd2に落ち着きます。
tkinterdnd2インストール時の注意
tkinterdnd2のインストールについて注意点があるので解説します。
tkinterdnd2はPyPIとcondaのどちらからでもインストールが可能です。
しかし、どちらでインストールしたかでimportの呼び出し方が変わるようなので注意が必要です。
違いは大文字か小文字かの違いです。
- インストール:
pip install tkinterdnd2
- 呼び出し方:
from tkinterdnd2 import *
またはfrom tkinterdnd2 import DND_FILES, TkinterDnD
- インストール:
conda install -c gagphil1 tkinterdnd2
- 呼び出し方:
from TkinterDnD2 import *
またはfrom TkinterDnD2 import DND_FILES, TkinterDnD
DnD時に禁止マークが出て実行不可になる現象が生じる(Windowsのみ)
さて、ここから本題です。
tkinterdnd2のインストールは問題なく、ソースコードの実行もエラーが出ないのですが、なぜかDnDができませんでした。
エクスプローラーからファイルをドラッグしてtkinterのウィンドウ上に持っていくと、何やら禁止マークが出てしまいます。
ネット上を探してもほぼ情報がなく、同じ現象で困っているという方がteratailで質問されていましたが、結局解決に至るコメントはついていませんでした(下記リンク参照)。
Tkinter2でファイルをフォーム画面にドラッグ&ドロップしたい
一旦Pythonから離れて、WindowsでDnDができなくなった時の対処法を一通りやりましたが、どれもダメでした。
一体何が原因なのかさらに調査したところようやく解決の糸口が見つかりました。
コマンドプロンプトでDnDができるかどうか確認
通常、コマンドプロンプトではファイルをDnDするとフルパスが表示されます。
しかし、フルパスが表示されるときとされないときがあることに気付きました。
どうやら管理者としてコマンドプロンプトを実行した場合にのみ、フルパスが表示されないということが分かりました。
すると以下の記事が見つかりました。
管理者モードで起動したアプリがドラッグアンドドロップ(D&D)出来ない問題(Windwos10 Pro)
要するにユーザーアカウント制御(UAC)がどうも悪さをしているようだということらしいのです。
ユーザーアカウント制御(UAC)が原因でDnDができない
そこで、一時的に全てのUACを無効にしてDnDをしてみました。
すると、、、できました!!
ひとまずこれで原因は特定できました。
しかし、UACを常に無効にしておくことはセキュリティ上よろしくありません。
再度UACを有効にして対策を考えます。
まず考えられることとしては特定のアプリケーションのみUACを無効化するというのが思い付きます。
実際、そのようなことはできるとネット上では多くの情報が検索できます。
しかし、ショートカットに対して無効化の設定をするようのなので、いまいちうまくできませんでした。
という訳で別の方法を模索することに・・・。
UACを無効にせず、仮想環境中のpython.exeを非管理者実行に設定
色々考えた結果、最終的にはUACを無効にせず、仮想環境中のpython.exeを非管理者実行に設定するというので解決しました。
Process Explorerでtkinterアプリ実行中に動いているプログラムを調べてみたところコマンドプロンプトと仮想環境中のpython.exeのみでした。
そして私の環境ではこのpython.exeが管理者として実行されるようにプロパティの互換性の部分で設定がされていました(自分でやった記憶はない)。
手順としては簡単で以下のようにするだけで、この問題を解決することができます。
これでもし解決できないようであれば「すべてのユーザーの設定を変更」から「管理者としてこのプログラムを実行する」のチェックを外してみてください。
これでようやくアプリケーション開発に専念できます・・・。
ですが、これは本来の仕様ではないかと。
なぜなら多くの方がこのような設定をすることなく使えている訳ですので、あくまでイレギュラーなものなのかもしれません。
このような問題が生じてしまう根本的な原因が何なのかはまだ分かっていません。
PCによるものものなのか、OSによるものなのか、それともAnacondaによるものなのか・・・。
少なくても私の使用しているWindows10のPCは古いものから新しいものまで全部で3台ありますが、全てで同じ現象が起きていました。
管理者権限を必要とするアプリケーション開発を行う際には今回の対処方法は使えませんので、別の方法も検討が必要になるかもですね。
ProgramDataにanacondaがインストールされている場合もdndできない
私が所有するWindowsのPC3台でtkinterdnd2はdndができなという同じ現象を生じていました。
しかし、どうやらそのうち1台(ノートPC)は原因が異なっていました。
理由は覚えていませんが、そのノートPCはanacondaがCドライブのProgramDataにインストールされていました。
anaconda導入時にインストール先として ” Just Me ” か ” All Users ” のどちらにするか聞かれます(上図)。
このとき、” Just Me ” にすると ” Users “フォルダにインストールされます。
” All Users ” にすると ” ProgramData ” フォルダにインストールされます。
どうやらanacondaがProgramDataフォルダにインストールされている場合も、tkinterdnd2は使えないようです。
実際、私のノートPCはProgramDataフォルダにanacondaがインストールされており、tkinterdnd2によるdndができませんでした。
anacondaをアンインストールして、” Just Me “を選択し、Usersフォルダにインストールするとdndができるようになりました。
これもtkinterdnd2によるdndができない原因の一つでしょう。
もしもanacondaがProgramDataフォルダにインストールされている場合は、インストールの見直しをしてみてください。
なお、anacondaで作った仮想環境のバックアップとリストア方法についてはこちらの記事で紹介していますので参考にしてください。
まとめ
kinterdnd2で開発したGUIにファイル等をドラッグ&ドロップしようとすると禁止マークが出てドロップできないという問題について解決策の解説をしました。
Windows限定の症状であり、UACが原因であることを特定しました。
また、UACを無効化することなく非管理者実行で解決できることを示しました。
他にもanacondaのインストールの先によってもdndができないという問題を特定しました。
tkinterdnd2でdndができないという方は上記の方法をお試しください。
Pythonのプログラム・GUIアプリケーションを作って仕事の効率化をお手伝いします!
科研費等での支払いにも対応しており、国立・私立大学の先生から複数の受注実績があります。
対応可能かどうかも含めてお気軽に問い合わせページからご相談ください。
OguLInks公式サイトのトップページに簡単な事例紹介もありますのでご参照ください。
Twitterでお得情報をゲットしたい方はフォローいただけると幸いです。
この記事が役に立ったという方、少額の御寄附をいただけますと小倉のモチベーションアップにつながります。
よろしければ以下より寄付いただけますと幸いですm(_ _)m
すでに購入済みの方はこちら