kakashi-blog・カカシブログ・

Python備忘録を書きドローンやバイクなど好きな事で生きて行こうとしているブログ

Python

Tkinterのメッセージボックスで出る謎ウインドウの消し方

投稿日:2020年10月4日 更新日:

Pythonのtkinterでメッセージボックスだけを出したいのに、何もない小さなウインドウ(謎ウインドウ)が一緒に出てきて、処理が止まってしまうことがあります。

結論から言うと、謎ウインドウの正体は tkinterが自動で作るルートウインドウ です。先に自分でルートウインドウを作って隠すか、使い終わったら root.destroy() で閉じれば解決します。

要点

  • messageboxは親になるウインドウが必要で、無ければ勝手にルートウインドウが作られます
  • よく紹介されているのは root.withdraw() で隠す方法です
  • 私の環境では、withdrawするとメッセージボックスまで見えなくなりました
  • root.destroy() でルートウインドウを閉じる方法なら、確実に先へ進めました

謎ウインドウが出て処理が止まる

Tkinterのmessageboxと一緒に出てくる空のウインドウ

次のコードを動かすと、メッセージボックスと一緒に謎ウインドウが出てきます。メッセージボックスのOKを押しても謎ウインドウが残り、最後の「OK」が表示されませんでした。

import tkinter as tk
from tkinter import messagebox

messagebox.showinfo('NEXT', 'つぎへ')
print('OK')

原因はルートウインドウの自動生成

tkinterのウインドウには、必ず一番大もとになる「ルートウインドウ」が必要です。messageboxを呼んだときにルートウインドウが無いと、tkinterが自動で作ります。これが謎ウインドウの正体です。

自動で作られたルートウインドウは誰も閉じないので、プログラムがそこで待ち続けてしまいます。

対処法1:root.withdraw()で隠す

調べると、多くの記事で紹介されているのがこの方法です。先にルートウインドウを自分で作り、withdraw() で隠してからメッセージボックスを出します。

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()
root.withdraw()
messagebox.showinfo('NEXT', 'つぎへ')
print('OK')

多くの人はこれでうまくいっているようです。ところが私の環境では、謎ウインドウと一緒にメッセージボックスまで見えなくなってしまいました。

withdrawでメッセージボックスが出ないとき

はっきりした原因はわかっていませんが、メッセージボックスが消えたのではなく、ほかのウインドウの後ろに隠れている可能性があります。その場合は、ルートウインドウを最前面に設定し、親として指定すると前に出てくるはずです。私の環境ではまだ試していないので、うまくいかないときは次の対処法2を使ってください。

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()
root.withdraw()
root.attributes('-topmost', True)
messagebox.showinfo('NEXT', 'つぎへ', parent=root)
root.destroy()
print('OK')

対処法2:root.destroy()で閉じる

私が最終的に使ったのはこの方法です。ルートウインドウを隠さずに作っておき、メッセージボックスを閉じたら destroy() でルートウインドウごと閉じます。

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()
messagebox.showinfo('NEXT', 'つぎへ')
root.destroy()
print('OK')

メッセージボックスが出ている間は空のウインドウも見えますが、OKを押すと両方閉じて、ちゃんと「OK」まで進みました。

見た目は少しかっこ悪いですが、確実に動くので、困ったらまずこの方法を試してみてください。もっとスマートな方法をご存じの方がいたら、コメントで教えてもらえるとうれしいです。

まとめ

  • 謎ウインドウの正体は、tkinterが自動で作るルートウインドウです
  • root = tk.Tk() で先に作り、withdraw() で隠すのが定番の方法です
  • withdrawでメッセージボックスが見えないときは、最前面の設定か destroy() で閉じる方法を試してください
  • 私の環境では destroy() で閉じる方法が確実でした

tkinterの基本的な使い方は、Python備忘録 Tkinter編② テキスト入力とボタンにまとめています。tkinterで作った計算カードアプリの記事もあります。

-Python
-

執筆者:


comment

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

関連記事

PythonでFizzBuzz問題を書く|3通りの書き方と1行コード

プログラミングの入門でよく出てくる「FizzBuzz問題」を、Pythonで書いてみました。 結論から言うと、3で割り切れるか、5で割り切れるか、両方か、を if で分けるだけ です。この記事では、私 …

Amazonのスクレイピングは禁止?Seleniumで試した結果と正しい方法

PythonでAmazonの商品名・価格・ASINコードを集めようとして、普通のスクレイピングでは取れず、何時間も悩んだことがあります。 結論から言うと、Amazonは利用規約でロボットなどによる自動 …

Seleniumで自動ログインする方法|Python備忘録

前回はSeleniumでブラウザをスクロールさせました。今回は、ログイン画面にIDとパスワードを自動で入力して、ログインするところまでやってみます。 結論から言うと、開発者ツール(F12)で入力欄とボ …

PythonのPillowで画像処理|切り抜き・回転・リサイズの基本

画像処理というと大げさですが、PythonのPillow(ピロー)を使って、画像を少し操作してみました。 結論から言うと、Image.open() で読み込めば、crop() で切り抜き、rotate …

Python Tkinter入門|ウインドウ・ラベル・入力欄・ボタンの基本

PythonのTkinter(ティーケーインター)を使うと、ボタンや入力欄のある画面(GUI)を作れます。この記事では、ウインドウを開いて、ラベル、テキストの入力欄、ボタンを付けるまでの基本をまとめま …