2

ここに質問を投稿したところ、コードを再構築するように勧められました。今では十分に異なっているので、新しい質問をすることは正当だと思います.

とにかく、リストボックスにドラッグ/ドロップ機能を追加しようとしていますが、最初のステップとして、イベントバインディングを最初に機能させることが適切であると考えました。現在、リストをクリックすると、リストボックスをクリックすると次のエラーが発生します。リストボックス ウィンドウが表示されますが、クリックするとエラーが発生します。

 "AttributeError: make_list instance has no attribute 'nearest'.

また、build_listbox メソッドで listbox を出力すると、次の 10 進数が .40720520L と出力されます。これはリストボックスに値を出力すべきではありませんか? 結局のところ、それは同じ方法にあります。リストボックスが正しく作成されていませんか?

from Tkinter import *
import Tkinter

class make_list:

    def move_mouse(self, event):
        self.curIndex = event.nearest(event.y)
        print self.curIndex

    def click_button(self, event):
        w= event.widget
        self.curIndex = int(w.curselection()[0])
        #print self.curIndex
        value = w.get(self.curIndex)
        print value

    def build_main_window(self):
        self.build_listbox()

    def build_listbox(self):
        listbox = Listbox()
        listbox.bind('<<ListboxSelect>>', self.click_button)
        listbox.bind('<B1-Motion>', self.move_mouse)
        for item in ["one", "two", "three", "four"]:
            listbox.insert(END, item)    
        listbox.insert(END, "a list entry")
        listbox.pack()
        print listbox
        return

if __name__ == '__main__':
    start = make_list()
    start.build_main_window()
    mainloop()
4

1 に答える 1

0

Tkinter ウィジェットでを実行したときに得られる値はprint、ユーザーにはほとんど関係がなく、Tcl作成された変数の名前にすぎません。

さて、コードが機能しているように見えるので (質問のコメントをすばやく確認することで)、別の方法でドラッグ アンド ドロップ機能を実行することをお勧めします。たとえば、 の値に関連付けられた値のリストがある場合、Listboxこのリストを更新して表示に反映できれば、タスクを実行するのがはるかに簡単になりますListboxよね? 残念ながら、Python にはそのような機能はありませんが、とりあえず次のコードを考えてみてください。

import Tkinter

def list_click(event):
    w = event.widget
    index = w.nearest(event.y)
    w._selection = index

def list_motion(event):
    w = event.widget
    if w._selection is None:
        return
    index = w.curselection()[0]
    w._var.swap(index, w._selection)
    w._selection = index

def list_clear(event):
    event.widget._selection = None

root = Tkinter.Tk()

v = ListVar(values=('one', 'two', 'three', 'four'))
v.append('a list entry')

listbox = Tkinter.Listbox(listvar=v)
listbox.pack()

listbox._selection = None
listbox._var = v
listbox.bind('<1>', list_click)
listbox.bind('<B1-Motion>', list_motion)
listbox.bind('<ButtonRelease-1>', list_clear)

root.mainloop()

このコードは次のように動作します: リストボックスでマウス クリックが発生すると、最も近い項目が「選択済み」としてマークされ、マウスを動かすと項目が交換されて選択が更新され、マウス ボタンを放すと選択がクリアされます。 . 欠けているのは、このListVarことです。ここにあります:

class ListVar(Tkinter.Variable):
    def __init__(self, master=None, name=None, **kwargs):
        Tkinter.Variable.__init__(self, master, kwargs.get('values'), name)

    def set(self, values):
        self._tk.call('set', self._name, values)

    def set_index(self, index, value):
        self._tk.call('lset', self._name, index, value)

    def get_index(self, index):
        return self._tk.eval('lindex $%s %d' % (self._name, index))

    def get(self, start=None, end=None):
        if start is None and end is None:
            res = self._tk.eval('lrange $%s 0 end' % self._name)
        elif end is None:
            res = self._tk.eval('lrange $%s %d end' % (self._name, start))
        else:
            res = self._tk.eval('lrange $%s %d %d' % (self._name, start, end))
        return self._tk.splitlist(res)

    def swap(self, a, b):
        if a != b:
            tmp = self.get_index(a)
            self.set_index(a, self.get_index(b))
            self.set_index(b, tmp)

    def append(self, value):
        self._tk.eval('lappend %s {%s}' % (self._name, value))

これは非常に大雑把で、"hello{" などの値を渡すと失敗します。これはさまざまな方法で改善できます。

于 2013-01-23T21:24:24.650 に答える