56107


解決策をご存知の方にご教示をお願いいたします。

**実現したいこと**  
大きさの決まったダイアログおよびLabelFrame内で、Treeviewを使用して表を表示したいです。  
表は見やすいように、カラムを項目に合わせて固定幅とします。そのため、決められた大きさの中で、Treeview上の表は表示しきれないので、縦横のスクロールバーが埋め込む有効な状態としたいです。

**現在の問題点**  
・Treeview上の表全体の幅が収めたい幅にならない。  
・Treeviewの幅が抑えられないので、横スクロールバーが有効にならない。

**サンプルコード**  
LabelFrame内にTreeviewおよびscrollbarを配置します。  
Treeviewには全体の幅するオプションがないので、LabelFrame.columnconfigureで指定するが無視されて、Treeviewの表データに合わせた幅になってしまっています。

**試したこと**  
以下のリンクについて、試しました。  
私の用途では、place()による配置は適していないため、2つ目のリンクの内容は参考になりませんでした。  
[Horizontal scrolling won't activate for ttk Treeview
widget](https://stackoverflow.com/questions/14359906/horizontal-scrolling-
wont-activate-for-ttk-treeview-widget)  
[python ttk
Notebookにtreeviewをグリッドで配置した時にスクロールバーが収まらない](https://teratail.com/questions/139274)

* * *
[code]

    #! /usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    import tkinter as tk
    from tkinter import ttk
    
    class CreateScreen(object):
        def __init__(self):
            self.screen_w = 300
            self.screen_h = 200
            self.dlg_pos_x = 10
            self.dlg_pos_y = 10
    
            return super().__init__()
    
        def createMainWindow(self):
    
            obj = ttk.tkinter.Tk() 
    
            geo_string = str(self.screen_w) + "x" + str(self.screen_h) + "+" + str(self.dlg_pos_x)  + "+" + str(self.dlg_pos_y) 
    
            obj.geometry(geo_string) 
    
            _InFrame_ = ttk.LabelFrame(
                obj,
                width = self.screen_w,
                height = self.screen_h,
                text = "決められた幅のフレーム内で表示したい。",
                )
    
            _TreeList_ = ttk.Treeview(
                _InFrame_,
                selectmode = 'none',
                show = "headings",
                height = 6,
                )
    
            tree_h_scroll = ttk.Scrollbar(
                _InFrame_,
                orient = tk.HORIZONTAL,
                command = _TreeList_.xview
                )
    
            tree_v_scroll = ttk.Scrollbar(
                _InFrame_,
                orient = tk.VERTICAL,
                command = _TreeList_.yview
                )
    
            _TreeList_['xscrollcommand'] = tree_h_scroll.set
            _TreeList_['yscrollcommand'] = tree_v_scroll.set
    
            tree = _TreeList_
            tree["columns"]=(1,2,3,4,5,6)
            tree.heading("#0",text = "")
            tree.heading(1,text = "項")
            tree.heading(2,text = "名前")
            tree.heading(3,text = "型式")
            tree.heading(4,text = "単価")
            tree.heading(5,text = "在庫数")
            tree.heading(6,text = "備考")
    
            tree.column(1, width = 30, stretch = False)
            tree.column(2, width = 100, stretch = False)
            tree.column(3, width = 150, stretch = False)
            tree.column(4, width = 50, stretch = False)
            tree.column(5, width = 50, stretch = False)
            tree.column(6, width = 150, stretch = False)
    
            tree_value = list()
    
            #適当にデータを埋め込む。
            for i in range(32):
                tree_value.append((i,"tree"+str(i),"T-"+str(i),i%5*1000+100,i%2*50,"*******"))
    
            for ch, val in enumerate(tree_value):
                tree.insert("",index = "end",tags = ch%2,value=val)
            else:
                tree.tag_configure(0,background = "lightcyan")
                tree.tag_configure(1,background = "white")
    
            _InFrame_.grid(padx = 5, pady = 5, ipadx = 5, ipady = 5)
            _InFrame_.columnconfigure(0, minsize = 250)
            _TreeList_.grid(row = 0,column = 0, sticky = tk.N+tk.S+tk.E+tk.W  )
            tree_h_scroll.grid(row = 1,column = 0,sticky = tk.EW )
            tree_v_scroll.grid(row = 0,column = 1,sticky = tk.NS )
    
            return obj
    
    if __name__ == '__main__':
        screen_obj = CreateScreen()
    
        MainWindow_obj = screen_obj.createMainWindow()
    
        MainWindow_obj.mainloop()
    
[/code]


CC BY-SA 4.0
2019-06-26T03:33:29.320
56104
2019-06-26T08:30:01.530
2019-06-26T03:56:32.420
3060
32891
question
python python3
Treeview内リストを固定幅にし、横スクロールバーを有効にしたい。

[code]

     _InFrame_.grid(padx = 5, pady = 5, ipadx = 5, ipady = 5)
     _InFrame_.columnconfigure(0, minsize = 250)
     _TreeList_.grid(row = 0,column = 0, sticky = tk.N+tk.S+tk.E+tk.W  )
     tree_h_scroll.grid(row = 1,column = 0,sticky = tk.EW )
     tree_v_scroll.grid(row = 0,column = 1,sticky = tk.NS )
    
[/code]

の箇所を

[code]

     _InFrame_.grid(padx = 5, pady = 5, ipadx = 5, ipady = 5)
     # 1列目を可変サイズとする
     _InFrame_.columnconfigure(0, weight=1)
     # 1行目を可変サイズとする        
     _InFrame_.rowconfigure(0, weight=1)
     # 内部のサイズに合わせたフレームサイズとしない
     _InFrame_.grid_propagate(False)
     _TreeList_.grid(row = 0,column = 0, sticky = tk.N+tk.S+tk.E+tk.W  )
     tree_h_scroll.grid(row = 1,column = 0,sticky = tk.EW )
     tree_v_scroll.grid(row = 0,column = 1,sticky = tk.NS )
    
[/code]

とすると良いかと思います。

[![画像の説明をここに入力](https://i.stack.imgur.com/Pjd66.png)](https://i.stack.imgur.com/Pjd66.png)


CC BY-SA 4.0
2019-06-26T05:52:15.977
56107
2019-06-26T05:52:15.977
24801
56104
answer


回答では無くて、上記質問の先に作ろうとしているらしきもの、の情報です。  
おそらく`DataGridView`のような感じでデータの表示と操作もやろうとしていると思われますが、こんなライブラリがあります。  
データ連携機能も組み込まれていて、開発量が減らせるのではないでしょうか。  
[dmnfarrell/tkintertable](https://github.com/dmnfarrell/tkintertable)

さらには同じ作者が pandas と連携した同様(おそらくもっと高機能)のライブラリを作っています。  
[dmnfarrell/pandastable](https://github.com/dmnfarrell/pandastable)

英語版StackOverflowの記事に、こんなのがあって、2番目の記事の回答がPython2.x用なんですが、これをPython3.x用に直す(2to3.pyに通す)と、@magichanさん回答のようなウインドウが表示されます。  
[Does tkinter have a table
widget?](https://stackoverflow.com/q/9348264/9014308)  
[Tkintertable Get selected Data](https://stackoverflow.com/q/19402998/9014308)

途中にある`self.table.model.load('save.table')`の`save.table`は、`tkintertable`リポジトリの`sample.table`に直して使っています。

[code]

    from tkinter import *
    from tkinter.ttk import *
    from tkintertable.Tables import TableCanvas
    from tkintertable.TableModels import TableModel
    
    class Application(Frame):
        def __init__(self, master=None):
            Frame.__init__(self, master)
            self.pack()
            self.model = TableModel()
            self.table = TableCanvas(self, model=self.model)
            self.table.createTableFrame()
            root.bind('<ButtonRelease-1>', self.clicked)   #Bind the click release event
    
            self.create_widgets()
    
        def create_widgets(self):
            self.table.model.load('sample.table')  #You don't have to load a model, but I usually
            self.table.redrawTable()             #Create a base model for my tables.
    
            d = dir(self.table)  #Will show you what you can do with tables.  add .model
                                 #to the end to see what you can do with the models.
            for i in d:
                print(i)
    
        def clicked(self, event):  #Click event callback function.
            #Probably needs better exception handling, but w/e.
            try:
                rclicked = self.table.get_row_clicked(event)
                cclicked = self.table.get_col_clicked(event)
                clicks = (rclicked, cclicked)
                print('clicks:', clicks)
            except: 
                print('Error')
            if clicks:
                #Now we try to get the value of the row+col that was clicked.
                try: print('single cell:', self.table.model.getValueAt(clicks[0], clicks[1]))
                except: print('No record at:', clicks)
    
                #This is how you can get the entire contents of a row.
                try: print('entire record:', self.table.model.getRecordAtRow(clicks[0]))
                except: print('No record at:', clicks)
    
    root = Tk()
    root.title('Table Test')
    app = Application(master=root)
    print('Starting mainloop()')
    app.mainloop()
    
[/code]

[![tkintertableの使い方サンプル表示](https://i.stack.imgur.com/4Y9Wx.png)](https://i.stack.imgur.com/4Y9Wx.png)


CC BY-SA 4.0
2019-06-26T08:30:01.530
56110
2019-06-26T08:30:01.530
26370
56104
answer