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

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

ただいまの
回答率

88.59%

Python/tkinterのフォームでメニューにより内容を消したり点けたりしたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,088

ky_46

score 93

 前提・実現したいこと

現在、VBAを得意にしていますが、近い将来pytonがExcelに搭載されると聞き、pythonの勉強を始めました。anacondaとPyCharmをインストールして、教本やビデオ教材などを実行してみています。

その中で、pythonでもGUIプログラムが書けると聞いて試作してみたのですが、希望の動作にならないので、ご相談です。

 該当のソースコード

#!/usr/bin/env python
# -*- coding: utf8 -*-
import sys
from tkinter import *
from selenium import webdriver

def btn0_callback():
    driver = webdriver.Firefox()
    driver.get("https://www.yahoo.co.jp/");


def btn1_callback():
    driver = webdriver.Firefox()
    driver.get("https://www.google.co.jp/");

def mrnu1_callback():
    button0 = Button(root, text = 'A',command=btn0_callback)
    button0.pack()

def mrnu2_callback():
    button1 = Button(root, text = 'B',command=btn1_callback)
    button1.pack()

if __name__ == '__main__':
    root = Tk()
    root.title(u"Software Title")
    root.geometry("400x300")

    menu_ROOT = Menu(root)
    root.configure(menu=menu_ROOT)

    menu_ROOT.add_command(label='A',command=mrnu1_callback)
    menu_ROOT.add_command(label='B',command=mrnu2_callback)

    root.mainloop()

 希望の動作

メニューのAを押したら、Aのボタンが現れ、ボタンを押すとYahoo!に飛ぶ
メニューのBを押したら、Aのボタンが消えて、Bのボタンが現れ、ボタンを押すとGoogleに飛ぶ
しかし、今はボタンが次々に増えてしまいます。

 最終的にやたい事

メニューを選ぶと、ウィンドウの中でそのメニューにあったボタンやテキストボックスが配置されるという切り替え動作がしたいです。

VBAでは、タブオブジェクトというのがあって、タブごとにボタンやテキストボックスを配置していました。
pythonはExcelも操作できるようなので、最終的にはVBAで表示しているフォームや計算を、pythonに移したいです。

よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

しかし、今はボタンが次々に増えてしまいます。

■原因

def mrnu1_callback():
button0 = Button(root, text = 'A',command=btn0_callback)
button0.pack()

メニューをクリックした時にmrnu1_callbackを呼び出していますが、毎回Button()のコンストラクタをよんでいます。その為新しいインスタンスが生成されpackで追加されます。

■本題
TkinterのNotebookウィジットを使ったサンプルです。
質問者様が求めているのはこういうコードでしょうか?

#!/usr/bin/env python
# -*- coding: utf8 -*-
import sys
import threading
from collections import OrderedDict
import functools
from tkinter import *
import tkinter.ttk as ttk

from selenium import webdriver


# メソッド名:task_runはあまり適切ではないかも!
def task_run(url):
    # webdriverをcloseしていないので、リソースリークに注意
    #driver = webdriver.Chrome(r'C:\selenium\chromedriver')
    driver = webdriver.Firefox()
    driver.get(url)


class Notebook(ttk.Notebook):
    def __init__(self, master=None, **kw):
        super().__init__(master, **kw)
        self.style = ttk.Style()
        # tabメニューのpaddingを設定
        self.style.configure('TNotebook.Tab', padding=(10, 0, 10, 0))
        self.tab_pages = OrderedDict()
        self.create_widgets()

    def create_widgets(self):
        # rootコンポーネントのwidthとheigthを取得
        width = self.master.winfo_width()
        height = self.master.winfo_height()
        self.tab_pages['tab_a'] = Frame(self, width=width, height=height)
        button_yahoo = Button(self.tab_pages['tab_a'],
                              command=functools.partial(Notebook.browser_open, 'https://www.yahoo.co.jp/'),
                              text='yahoo')
        button_yahoo.pack()

        self.tab_pages['tab_b'] = Frame(self, width=width, height=height)
        button_google = Button(self.tab_pages['tab_b'],
                               command=functools.partial(Notebook.browser_open, 'https://www.google.co.jp/'),
                               text='google')
        button_google.pack()
        for key, val in self.tab_pages.items():
            val.pack()
            # 登録されるtab名称(text)はOrderedDictのkey名
            self.add(val, text=key)
        self.pack(expand=True, fill=BOTH)

    @staticmethod
    def browser_open(url):
        # webdriverの生成に時間がかかり、イベントディスパッチスレッドがブロックするのを防ぐために別スレッドを生成する。
        thr = threading.Thread(target=task_run, args=(url,))
        thr.start()


def main():
    root = Tk()
    root.title(u"Software Title")
    root.geometry("400x300")
    root.update_idletasks()
    notebook = Notebook(root)
    root.mainloop()


if __name__ == '__main__':
    main()

■参考情報

  1. tkinterでタブを実装
  2. Changing the tab sizes of a Notebook widget in Python 3
  3. collections.OrderedDict
  4. functools.partial
  5. threading.Thread

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/02/05 10:37

    ご返答遅くなって申し訳ありません。
    確かに希望の動作です。
    変更点をいろいろいじって、メニューの切り替えができるようにしてみたいと思います。
    サンプルも参考にさせていただきます。VBAのフォームにあるタブも、pytonにあるのですね。調査不足でお恥ずかしいです。

    キャンセル

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

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

関連した質問

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