TransWikia.com

Tkinter サブウィンドウに配置したコンボボックスの値を取得したいが、エラーになってしまう

スタック・オーバーフロー Asked by jjkinder on February 21, 2021

プログラムミングを始めたばかりです。
ウィンドウ、コンボボックスの表示まではできるのですが、コンボボックスで項目の選択をするとエラーになってしまいます。
下記、ビットデバイスのタイプを取得の部分です。
いろいろ試しているのですが、うまくいきません。宜しくお願い致します。

import tkinter as tk
import tkinter.ttk as ttk
import sys
from tkinter.filedialog import askopenfilename 
from tkinter import *

class mainwindow(tk.Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.master.title("TEST")          # ウィンドウタイトルの設定
        self.master.geometry("600x600")    # ウィンドウサイズの設定

        self.pack()         # メインフレームの配置
        self.create_menu()  # メニューの生成
    
    # メニューの生成
    def create_menu(self):

        # 設定ウィンドウを開く
        def winsetting():
            settingwin=Toplevel(self)
            settingwin.title("SUB")
            settingwin.geometry("300x300")
            # modalに設定(このウィンドウが閉じるまではほかのウィンドウ操作をできなくする)
            settingwin.grab_set()

            # 部品の配置
            label_bittype=tk.Label(settingwin,text="bit device Type")
            label_bittype.place(x=5,y=70)
            # ビットデバイスタイプ
            bit_type=ttk.Combobox(settingwin,values=("A","B","C","D","E"),state="readonly")
            bit_type.bind("<<ComboboxSelected>>",get_bititem)
            bit_type.place(x=100,y=70)

        # ビットデバイスのタイプを取得 <---------ここでエラーになります。
        def get_bititem(self,event):
            print(bit_type.get())
    
        self.menubar=tk.Menu(self)     # Menuクラスからmenubarインスタンスを生成
        root.config(menu=self.menubar) # メニューバーの配置
 
        self.setting_menu=tk.Menu(self.menubar,tearoff=0)    #メニューバーに大項目"設定"を生成
        self.menubar.add_cascade(label="設定",menu=self.setting_menu)  # 大項目"設定"を設置
        self.setting_menu.add_command(label="設定",command=winsetting)    # 小項目"設定"を割り当て

if __name__ == "__main__":
    root=tk.Tk()
    app=mainwindow(master=root)
    app.mainloop()

One Answer

取り敢えず2つのタイプの修正が考えられます。####でコメントした部分が修正点です。
どちらが良いかはなんとも言えませんし、もっと良い方法があるかもしれません。

いずれにしても変数や関数/メソッドを何処に定義/所属させて、何処からアクセスできるようにするか、を明確にしておいた方が良いでしょう。


参考:Simple ttk ComboBox demo

  • def get_bititem(self,event):def create_menu(self):の中からclass mainwindow(tk.Frame):の中に移動。
  • bit_type.bind("<<ComboboxSelected>>",get_bititem)のcallbackルーチン指定にself.が不足。self.get_bititemに変更。
  • def winsetting():def get_bititem(self,event):bit_typeの前にself.が不足。それぞれself.bit_typeに変更。
import tkinter as tk
import tkinter.ttk as ttk
import sys
from tkinter.filedialog import askopenfilename 
from tkinter import *

class mainwindow(tk.Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.master.title("TEST")    # ウィンドウタイトルの設定
        self.master.geometry("600x600")    # ウィンドウサイズの設定
        self.pack()     # メインフレームの配置
        self.create_menu()  # メニューの生成

    #### 定義位置を移動
    # ビットデバイスのタイプを取得
    def get_bititem(self,event):
        print(self.bit_type.get())    #### self. を追加

    # メニューの生成
    def create_menu(self):
        # 設定ウィンドウを開く
        def winsetting():
            settingwin=Toplevel(self)
            settingwin.title("SUB")
            settingwin.geometry("300x300")
            # modalに設定(このウィンドウが閉じるまではほかのウィンドウ操作をできなくする)
            settingwin.grab_set()

            # 部品の配置
            label_bittype=tk.Label(settingwin,text="bit device Type")
            label_bittype.place(x=5,y=70)
            # ビットデバイスタイプ
            self.bit_type=ttk.Combobox(settingwin,values=("A","B","C","D","E"),state="readonly")  #### self. を追加
            self.bit_type.bind("<<ComboboxSelected>>",self.get_bititem)                           #### self. を追加
            self.bit_type.place(x=100,y=70)                                                       #### self. を追加

        self.menubar=tk.Menu(self)  # Menuクラスからmenubarインスタンスを生成
        root.config(menu=self.menubar)# メニューバーの配置

        self.setting_menu=tk.Menu(self.menubar,tearoff=0)    #メニューバーに大項目"設定"を生成
        self.menubar.add_cascade(label="設定",menu=self.setting_menu)  # 大項目"設定"を設置
        self.setting_menu.add_command(label="設定",command=winsetting)    # 小項目"設定"を割り当て

if __name__ == "__main__":
    root=tk.Tk()
    app=mainwindow(master=root)
    app.mainloop()

参考:Tkinter チュートリアル - コンボボックス Combobox

  • def get_bititem(self,event):self,が余計。eventだけで良くてdef get_bititem(event):とする。
  • def get_bititem(event):の定義位置はdef create_menu(self):の中では無く、def winsetting():の中でbit_type.bind("<<ComboboxSelected>>",get_bititem)の前に定義する。
import tkinter as tk
import tkinter.ttk as ttk
import sys
from tkinter.filedialog import askopenfilename 
from tkinter import *

class mainwindow(tk.Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.master.title("TEST")    # ウィンドウタイトルの設定
        self.master.geometry("600x600")    # ウィンドウサイズの設定
        self.pack()     # メインフレームの配置
        self.create_menu()  # メニューの生成

    # メニューの生成
    def create_menu(self):
        # 設定ウィンドウを開く
        def winsetting():
            settingwin=Toplevel(self)
            settingwin.title("SUB")
            settingwin.geometry("300x300")
            # modalに設定(このウィンドウが閉じるまではほかのウィンドウ操作をできなくする)
            settingwin.grab_set()

            #### 定義位置を移動
            # ビットデバイスのタイプを取得
            def get_bititem(event):    #### self, を削除
                print(bit_type.get())

            # 部品の配置
            label_bittype=tk.Label(settingwin,text="bit device Type")
            label_bittype.place(x=5,y=70)
            # ビットデバイスタイプ
            bit_type=ttk.Combobox(settingwin,values=("A","B","C","D","E"),state="readonly")
            bit_type.bind("<<ComboboxSelected>>",get_bititem)
            bit_type.place(x=100,y=70)

        self.menubar=tk.Menu(self)  # Menuクラスからmenubarインスタンスを生成
        root.config(menu=self.menubar)# メニューバーの配置

        self.setting_menu=tk.Menu(self.menubar,tearoff=0)    #メニューバーに大項目"設定"を生成
        self.menubar.add_cascade(label="設定",menu=self.setting_menu)  # 大項目"設定"を設置
        self.setting_menu.add_command(label="設定",command=winsetting)    # 小項目"設定"を割り当て

if __name__ == "__main__":
    root=tk.Tk()
    app=mainwindow(master=root)
    app.mainloop()

Answered by kunif on February 21, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP