2016-08-30 7 views
0

私はユーザーが項目をドラッグしたり移動して並べ替えることができるドラッグアンドドロップリストボックス(found here)を持っています。 Python Tkinterリストボックスアイテムを保存するSqliteデータベースへの注文

は、私が最初にこのようになります db.sqliteファイルがあります:

>>> make_df() 
    ordering   fruit 
0   0   apples 
1   1  oranges 
2   2 blueberries 
3   3  watermelon 
4   4  cantaloupe 
5   5   pears 
6   6 pomegranate 
7   7 raspberries 
8   8 blackberries 
9   9 boysenberries 
10  10  nectarines 

私は何をしようとしていますが、私はときに再起動し、リストボックスの周りのアイテムを並べ替えると順序がデータベースに保存されているということですがプログラムでは、アイテムは前回使用したときと同じ順番で表示されます。

問題: プログラムを再起動するたびに、リストボックスの項目は常に同じ順序になります。しかし、アイテムを並べ替えると、make_dfを実行してデータベースを参照して順序を確認し、データフレームを返します。そのセッション中にデータベースが更新されたことが示されます。 それは永久にそれを保存していないだけで、それは私が把握できないものです。

Example

import tkinter as tk 
import pandas as pd 
import sqlite3 
root = tk.Tk() 

def make_sqlite_db_for_stackoverflow(): 
    connection = sqlite3.connect('db.sqlite') 
    db_file_name = 'db.sqlite' 
    df = pd.DataFrame(
    [(0, 'apples'), (1, 'oranges'), (2, 'blueberries'), (3, 'watermelon'), 
    (4, 'cantaloupe'), (5, 'pears'), (6, 'pomegranate'), (7, 'raspberries'), 
    (8, 'blackberries'), (9, 'boysenberries'), (10, 'nectarines')], 
    columns=['ordering', 'fruit'] 
    ) 
    df.to_sql('columns', connection, index=False, if_exists='replace') 
    connection.close() 

make_sqlite_db_for_stackoverflow() 

def make_df(): 
    print(pd.DataFrame(sqlite3.connect('db.sqlite').cursor().execute(
    'SELECT * FROM columns ORDER BY "ordering";').fetchall(), columns=['ordering', 'fruit'])) 

class Drag_and_Drop_Listbox(tk.Listbox): 
    """ A tk listbox with drag'n'drop reordering of entries. """ 
    def __init__(self, master, **kw): 
    kw['selectmode'] = tk.EXTENDED 
    tk.Listbox.__init__(self, master, kw) 
    self.bind('<Button-1>', self.setCurrent) 
    self.bind('<B1-Motion>', self.shiftSelection) 
    self.curIndex = None 
    def setCurrent(self, event): 
    self.curIndex = self.nearest(event.y) 
    def shiftSelection(self, event): 
    i = self.nearest(event.y) 
    if i < self.curIndex: 
     x = self.get(i) 
     self.delete(i) 
     self.insert(i+1, x) 
     self.curIndex = i 
    elif i > self.curIndex: 
     x = self.get(i) 
     self.delete(i) 
     self.insert(i-1, x) 
     self.curIndex = i 

def update_ordering(*args): 
    connect = sqlite3.connect('db.sqlite') 
    cursor = connect.cursor() 
    field_ordering = [(order,fruit) for order,fruit in enumerate(ddlistbox.get(0, 'end'))] 
    print(field_ordering) 
    for field in field_ordering: 
    cursor.execute("UPDATE columns SET 'ordering'="+str(field[0])+" WHERE fruit='"+field[1]+"';") 
    connect.commit() 
    connect.close() 
    print(ddlistbox.curselection()) 

scrollbar = tk.Scrollbar(root, orient="vertical") 
ddlistbox = Drag_and_Drop_Listbox(root, yscrollcommand=scrollbar.set) 
scrollbar.grid(row=0, column=1, sticky='ns') 
scrollbar.config(command=ddlistbox.yview) 

def get_sqlite_report_fields(): 
    conn = sqlite3.connect('db.sqlite') 
    conn.row_factory = lambda cursor, row: row[0] 
    cursor = conn.cursor() 
    fetch = cursor.execute("SELECT fruit FROM columns ORDER BY 'ordering';").fetchall() 
    conn.close() 
    return fetch 

for fruit in get_sqlite_report_fields(): 
    ddlistbox.insert(0, fruit) 
ddlistbox.config(width=30) 
ddlistbox.bind('<Double-Button-1>' , func=update_ordering) 
ddlistbox.grid(row=0, column=0) 

button = tk.Button(root, text='Check', command=update_ordering) 
button.grid(row=1, column=0) 

root.mainloop() 
+0

コードは機能していますか?それは例外を発生させますか? – FamousJameous

+0

あなたのデータベーストランザクションに 'commit'がありませんか? – FamousJameous

+0

私は 'update_ordering'関数で順序を更新するときに' commit'を使用しています。それ以外の時は、データベースから 'SELECT'して更新していません。 – Jarad

答えて

1

非常に私は私の解決策を掲載していますので、誰もが私の質問に答えないだろう。これは、ドラッグアンドドロップのリストボックスを使用して、ユーザーがリストボックス内のアイテムを並べ替えることを可能にし、次回のためにアイテムの並べ替えをデータベースに保存します。

import tkinter as tk 
import pandas as pd 
import sqlite3 
root = tk.Tk() 

class Drag_and_Drop_Listbox(tk.Listbox): 
    """ A tk listbox with drag'n'drop reordering of entries. """ 
    def __init__(self, master, **kw): 
    kw['selectmode'] = tk.EXTENDED 
    tk.Listbox.__init__(self, master, kw) 
    self.bind('<Button-1>', self.setCurrent) 
    self.bind('<B1-Motion>', self.shiftSelection) 
    self.curIndex = None 
    def setCurrent(self, event): 
    self.curIndex = self.nearest(event.y) 
    def shiftSelection(self, event): 
    i = self.nearest(event.y) 
    if i < self.curIndex: 
     x = self.get(i) 
     self.delete(i) 
     self.insert(i+1, x) 
     self.curIndex = i 
    elif i > self.curIndex: 
     x = self.get(i) 
     self.delete(i) 
     self.insert(i-1, x) 
     self.curIndex = i 

def update_ordering(*args): 
    connect = sqlite3.connect('db.sqlite') 
    cursor = connect.cursor() 
    field_ordering = [(order,fruit) for order,fruit in enumerate(ddlistbox.get(0, 'end'))] 
    print(field_ordering) 
    for field in field_ordering: 
    cursor.execute("UPDATE columns SET 'ordering'="+str(field[0])+" WHERE fruit='"+field[1]+"';") 
    connect.commit() 
    connect.close() 
    print(ddlistbox.curselection()) 

scrollbar = tk.Scrollbar(root, orient="vertical") 
ddlistbox = Drag_and_Drop_Listbox(root, yscrollcommand=scrollbar.set, activestyle='none') 
scrollbar.grid(row=0, column=1, sticky='ns') 
scrollbar.config(command=ddlistbox.yview) 

conn = sqlite3.connect('db.sqlite') 
conn.row_factory = lambda cursor, row: row[0] 
cursor = conn.cursor() 
fetch = cursor.execute("SELECT fruit FROM columns ORDER BY ordering ASC").fetchall() 
for field in fetch: 
    ddlistbox.insert(tk.END, field) 
ddlistbox.config(width=30) 
ddlistbox.grid(row=0, column=0) 

button = tk.Button(root, text='Check', command=update_ordering) 
button.grid(row=1, column=0) 

root.mainloop() 
関連する問題