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

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

新規登録して質問してみよう
ただいま回答率
85.35%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

7659閲覧

PYTHON treeviewのcolumnで表示指定しない項目のデータ入手法

akiteru

総合スコア21

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/04/13 08:21

前提・実現したいこと

SQLiteで自分用住所録を作りたい。テーブルにはId,Name,Hurigana,Adress,TelNo,Bikou等のフィールドがあります(Idがキーで第1フィールドです)。フリガナを入力し部分検索し結果をfetchall()で入手、treeviewで表示しています。但し主要な一部のフィールドのみ表示。treeviewに<<TreeviewSelect>>設定し
フォーカスされた行の表示内容は見られますが、下記の実現方法が判りません、ご教授ください。

ここに質問の内容を詳しく書いてください。
「実現したいこと」
(1)このtreeviewでの選択行とfetchall()で入手しているデータを連動させtreeviewでは表示しない
がfetchall()データ内にはあるIdのデータをフォームのENTRY内に表示させたい。
(2)表示されているIdデータ表示領域に有るボタン操作でfetchall()を「前データ」、「後データ」
にスキップし表示させる。この時treeviewのフォーカスも連動して移動させる
(3)2と同様にSQL文で抽出操作されたテーブルデータ内(複数件数あり)のカーソルを移動させる。
私の現状では(1)でIdデータが入手できれば、移動の都度に移動後のIdデータで再検索し1件に絞る方法です

該当のソースコード

# tesy.py import tkinter as tk import tkinter.ttk as ttk # SQLite3の接続モジュールをインポートする import sqlite3 class MainWindow(ttk.Frame): def __init__(self, parent): super(MainWindow, self).__init__(parent) self.parent = parent self.selected_list = () #**********データベース接続 self.conn = sqlite3.connect("PyPostDb.db") self.cur = self.conn.cursor() self.create_form() self.pack() #********画面作成 def create_form(self): #*******結果リストページ画面(タブ2) # タブ2の表題の設定 self.label2_0 = tk.Label(text="【検索結果リスト】",font=("",16),height=2) self.label2_0.pack(fill="x") # ふりがなのラベルとエントリーの設定 self.frame1_2 = tk.Frame(self,pady=10) self.frame1_2.pack() self.label1_2 = tk.Label(self.frame1_2,font=("",14),text="フリガナ") self.label1_2.pack(side="left") self.entry1_2 = tk.Entry(self.frame1_2,font=("",14),justify="left",width=15) self.entry1_2.pack(side="left") self.frame1_3 = tk.Frame(self,pady=10) self.frame1_3.pack() self.btnSearch = tk.Button(self.frame1_3, text='検 索', command=self.btn_Search) self.btnSearch.pack() # ツリービューの作成 self.frame1_4 = tk.Frame(self,pady=10) self.frame1_4.pack() self.tree = ttk.Treeview(self.frame1_4) # ツリービューの配置 self.tree.place(relheight=0.95,relwidth=0.95,relx=0.0,rely=0.0) # ******特定行が選択された時、行データをタプルで受け取る self.tree.bind('<<TreeviewSelect>>',lambda event: self.tree_selected(event)) # 列インデックスの作成 self.tree["columns"] = (1,2,3) # 表スタイルの設定(headingsはツリー形式ではない、通常の表形式) self.tree["show"] = "headings" # 各列の設定(インデックス,オプション(今回は幅を指定)) self.tree.column(1,width=200) self.tree.column(2,width=200) self.tree.column(3,width=200) # 各列のヘッダー設定(インデックス,テキスト) self.tree.heading(1,text="名 前") self.tree.heading(2,text="住 所") self.tree.heading(3,text="電 話") # ツリービューの配置 self.tree.pack() # *********treeviewで選択された行の詳細データ表示および「前進」【後退」ボタン self.frame1_5 = tk.Frame(self,pady=10) self.frame1_5.pack() self.label1_5= tk.Label(self.frame1_5,font=14,text="ID番号") self.label1_5.pack(side="left") self.entry1_5 = tk.Entry(self.frame1_5,font=14,justify="left",width=15) self.entry1_5.pack(side="left") self.frame1_6 = tk.Frame(self,pady=10) self.frame1_6.pack() self.btnBack = tk.Button(self.frame1_6, text='前 進', command=self.btn_Ahead) self.btnBack.pack(side ='left') self.btnBack = tk.Button(self.frame1_6, text='後 退', command=self.btn_Back) self.btnBack.pack(side ='right') # ******* 各ボタン等のアクション def btn_Search(self): # ***** 前回の表示データを削除 for i in self.tree.get_children(): self.tree.delete(i) # ******入力された検索条件入手SQL文作成 huri = str.strip(self.entry1_2.get()) sql = 'SELECT * FROM PyPostTbl' sql = sql + " WHERE (PyPostTbl.Huri LIKE '%" + huri + "%')" # SELECT文で取得した各レコード取得 self.cur.execute(sql) row_selected = self.cur.fetchall() # ツリービューに表示 for row in row_selected: dummy = (row[2],row[4],row[8]) self.tree.insert("","end",values=dummy) def btn_Ahead(self): print('fetchall()したデータを1件前進表示') def btn_Back(self): print('fetchall()したデータを1件後退表示') def tree_selected(self,event): # ******** リストタブ内のグリッド表示内で行選択されたとき選択行のデータ保持。1件データ絞りに使用 self.selected_list = () selected_items = self.tree.selection() if selected_items: self.selected_list = self.tree.item(selected_items[0], 'values') print(self.selected_list) # ****** 終了処理 def quit(self, event=None): # 終了時の処理 self.conn.close() self.master.destroy() application = tk.Tk() application.geometry("1000x600") application.title('PyPost') window = MainWindow(application) application.protocol('WM_DELETE_WINDOW', window.quit) application.mainloop() ソースコード

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

(1)このtreeviewでの選択行とfetchall()で入手しているデータを連動させtreeviewでは表示しない

がfetchall()データ内にはあるIdのデータをフォームのENTRY内に表示させたい。

  • Treeview の "displaycolumns" を設定すると非表示の column を作れます
  • もしくは、幅ゼロ width=0, minwidth=0 設定の column を作る。
  • ID のデータも一緒に Treeview へ insert します。

python

1tree["columns"] = ["id", "name", "addr"] # 例 2# heading() column() を設定した後 3tree["displaycolumns"] = ["name", "addr"] # id を抜いたリストを設定で、idのみ非表示に。

selected_list で選択した行のデータは所得出来てました。
後は得られたIDを Entry に反映させるだけです。(StringVarを使う方法が簡単)

(2)表示されているIdデータ表示領域に有るボタン操作でfetchall()を「前データ」、「後データ」

にスキップし表示させる。この時treeviewのフォーカスも連動して移動させる

(3)2と同様にSQL文で抽出操作されたテーブルデータ内(複数件数あり)のカーソルを移動させる。

「前データ」と「後データ」が良く解りませんでした、
カーソルとはデータベースのカーソルでしょうか?(次 10 件みたいな操作?)
ツリービュー内の選択された行を指すのでしょうか?(選択された行が上下に動く)

前者は、SQL の LIMIT と OFFSET で実現できます。
Python 側では、現在表示しているのが何ページ目のなのかを覚えて起きます。

後者だとして、選択された行を動かすサンプルです。selection_set を使います。
後進(上の行のアイテム)は、 next -> prev に変えると得られます。
(末端まで移動した後のエラー処理は省略)

python

1 def btn_Ahead(self): 2 print('fetchall()したデータを1件前進表示') 3 for item in self.tree.selection(): 4 self.tree.selection_set(self.tree.next(item)) 5 break

イメージ説明

投稿2020/04/13 15:37

編集2020/04/13 16:10
teamikl

総合スコア8760

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akiteru

2020/04/14 05:48

いつもサポートしていただき有難うございます。結果としてはまさにやりたい事です。"displaycolumns"にこんな裏技が有るとはていただき有難うございます。結果としてはまさにやりたい事です。"displaycolumns"にこんな裏技が有るとはtkinterのレファレンスを見ても気が付きませんでした。 私の勝手なイメージは次の通りでした【SQL文で抽出されたself.cur.execute(sql)のデータ行が有り、これを参照しているself.cur.fetchall()が有り取り込んだデータには連番が有るのでは?、またfetchall()をtrieviewに表示しおりこれにも行の連番が有る。二つの連番は1対1で対応しておりtreeviewのフォーカスされた時、この連番を取得できれば、treeviewに非表示のIdフィールドの値をfetchall()のデータから取れる。又self.cur.execute(sql)のデータ行をこの連番を使いスキップさせ指定のレコードを特定し編集等のデータ書き換え後保存できるのでは?】。 「前進、後退」は別のタブで選択行の全項目を表示し、これをリスト表示中の行とリンクして前、後退させることを想定しています。希望の結果は回答により実現可能と思います、ありがとうございました
teamikl

2020/04/15 08:20 編集

SQL の CREATE TABLE で PRIMARY KEY 設定したものが連番になります。 "SELECT * FROM PyPostTbl" "SELECT Id, Name,Adress,TelNo FROM PyPostTbl" (※テーブル定義が解らないので、カラム名は推測です) の様に変更すると、dummy での取り出しが不要になり rowは Id,Name,Address,TelNo 項目のみ取り出したリストになります。 >この連番を使いスキップさせ指定のレコードを特定し これは、Id さえ控えていれば SQL で出来るので、 SQL の”WHERE 句”について調べてみてください。
teamikl

2020/04/15 08:18

あと、オフトピになりますが # ******特定行が選択された時、行データをタプルで受け取る 今回の場合、ここは lambda不要でそのまま設定できます。 self.tree.bind('<<TreeviewSelect>>', self.tree_selected)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問