質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.60%

Python3でGUIをtkinterで後付したい。

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,506

score 10

 Python3でGUIをtkinterで後付したい。

python3で画像のヒストグラム調整をしたりするプログラムを書きました。
CUIでファイルの場所を入力すると自動で調整された画像が出力されるように作成しました。
このプログラムにGUIを足したいと思いTkinterを用いたのですが、うまくいきません。

TkinterでGUIを作成して、ファイルの場所を入力する場所を作り、ボタンを押すとファイルの場所を取得するところまではうまくいったのですが、ウィンドウを閉じないと得られたファイルの値を調整プログラムに渡せません。

このように、すでにCUIで処理を作成して、ここに必要な引数を入力するために後付で入力用のインターフェイスとしてGUIを作成する際に最も良い方法をご存知でしたら教えていただけると幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+1

ヒストグラム調整プログラムというのはこんな雰囲気に作成されたのだと思います。

・(A)初期化など
・(B)filename = input('enter filename: ') <==入力
・(C)画像読み込み/ヒストグラム調整等の計算
・(D)画像を表示 ==> 出力

上記のようにCUIアプリは「メインプログラムが実行する順序を自ら制御して順に必要な処理を行う」ように作りますが、GUIプログラムの場合、プログラムの制御は「画面を操作する利用者が握る」構造になっています。例えばTkinterを使うと

...

root = tk.Tk()
画面の初期化
root.mainloop()  # この関数がGUIを表示している間全ての制御を司る
                 # (プログラマーが自由に処理順を決められない。全てmainloop()が支配する)
     <-- ユーザーがボタンをクリック
     --> ボタン操作に対するハンドラー関数が呼び出される
     <-- ユーザーがキー入力
     --> キー操作に対するハンドラー関数が呼び出される
     ...
     <-- ウィンドウを閉じる(通常はGUIアプリの終了操作)
このタイミングでようやくmainloopが終了
GUIプログラムではmainloop()が終わったらアプリケーションの終了になる

こんなふうに制御の流れがCUI/GUIでは大きく異なります。この「利用者がGUIを操作する度に必要な処理を行う」という制御方式をイベント駆動方式なんて言い方をします。

元々CUIで作成していたプログラムをCUIにする(多分)最も素朴な方法は

  • プログラムの各段階を「関数分割する」
    例えば最初に述べたCUIの各段階((A)~(D))をそれぞれ関数に分割します。
  • それぞれの関数をイベント駆動方式の中の各ハンドラーの中から呼び出すようにする
    もし最初に書いたような内容ですと(A)をmainloopの前に実行し、ファイル名をGUIで入力させて計算開始を指示するボタンなどを押したときのハンドラーから(B)~(D)を呼び出すようにします。

といった感じだと思います。要するに今まで主たる制御を行っていたCUIのコードでプログラムの制御を支配するのではなく、あくまでGUIを司るmainloop()関数に制御を支配させ、従来のCUIコードは「mainloop()の中から自動的に呼び出されるハンドラーからさらに呼び出されるサブルーチン」にするのです。

本来なら画像処理など時間がかかる処理をハンドラーの中から直接呼び出すのはGUIアプリケーションとしてあまりよくないのですが(なぜなら時間がかかる処理をやっている間、画面がフリーズしたような状態になるから)、とりあえず動かすためにはまずこのあたりを目指して作ってみるとよいのではないでしょうか?

長時間の計算中でも画面がフリーズするようなことなく「いつでもキャンセルボタンを押せる」ような作りにするには長時間かかる処理を別のスレッドにすればよいのですが、それはまた別の課題として考えるのがよいのではないかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/13 12:38

    ありがとうございます。GUIを用いるのは初めてだったため非常に参考になりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る