Python/Tkinter列表框故障

Python/Tkinter列表框故障,python,events,listbox,widget,tkinter,Python,Events,Listbox,Widget,Tkinter,我发布了一个问题,有人建议我重组代码。现在已经完全不同了,我觉得有理由问一个新问题 无论如何,我正在尝试向列表框添加拖放功能,但我认为一个好的第一步是首先让事件绑定工作。当前,当我单击列表时,单击列表框时会出现以下错误。此时会出现listbox窗口,但单击它时会出现错误 "AttributeError: make_list instance has no attribute 'nearest'. 另外,当我在build_listbox方法中打印listbox时,将打印以下十进制数。40720

我发布了一个问题,有人建议我重组代码。现在已经完全不同了,我觉得有理由问一个新问题

无论如何,我正在尝试向列表框添加拖放功能,但我认为一个好的第一步是首先让事件绑定工作。当前,当我单击列表时,单击列表框时会出现以下错误。此时会出现listbox窗口,但单击它时会出现错误

 "AttributeError: make_list instance has no attribute 'nearest'.
另外,当我在build_listbox方法中打印listbox时,将打印以下十进制数。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()
从Tkinter导入*
进口Tkinter
班级名单:
def移动鼠标(自身,事件):
self.curIndex=事件最近(事件y)
打印self.curIndex
def点击按钮(自身,事件):
w=事件.widget
self.curIndex=int(w.curselection()[0])
#打印self.curIndex
值=w.get(self.curIndex)
打印值
def build_主窗口(自):
self.build_listbox()
def build_列表框(自身):
listbox=listbox()
listbox.bind(“”,self.click_按钮)
listbox.bind(“”,self.move\u鼠标)
对于[“一”、“二”、“三”、“四”]中的项目:
列表框.插入(结束,项目)
listbox.insert(结束,“列表条目”)
listbox.pack()
打印列表框
返回
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
开始=制作列表()
start.build\u主窗口()
mainloop()

在Tkinter小部件上执行
打印时得到的值与用户基本无关,它只是为您创建的
Tcl
变量的名称

现在,由于显然您的代码正在工作(通过快速浏览问题中的注释),我建议以不同的方式执行拖放功能。例如,如果我们有一个与
列表框
中的值相关联的值列表,那么如果我们可以更新此列表,然后它将反映在
列表框
显示上,那么执行任务就会容易得多,对吗?可惜的是我们在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()

这是非常粗糙的,如果你传递一个像“hello{”这样的值,就会失败。这可以在很多方面得到改进。

你能发布完整的回溯以便我们知道哪一行生成异常吗?实际上你得到的是一个
属性错误:事件实例在
move\u mouse()的第一行没有属性“nearest”
定义。这是因为
事件
对象没有
最近的
方法函数属性。顺便说一句,类的PEP 8命名约定是
CapCase
,所以
生成列表
应该是
生成列表
列表框
对象有
游标选择()
返回所选元素行号的方法这是您应该使用的。我建议您花一些时间阅读web上和各种书籍中存在的许多
Tkinter
中的一种。对不起,我的错误。
listvariable
是widget选项而非属性,因此使用
listbox.cget('listvariable')检索其当前值
--但是,由于未知原因,它返回一个空字符串。工作的是
listbox.get(0,END)
它返回元组
('one','two','three','four','a list entry')
。顺便说一句,在
build\u listbox()中创建的
listbox
实例
存储在局部变量
listbox
中,并在函数返回时自动删除,因此我建议您(或同时)将该值指定给
self.listbox
,以防止发生这种情况。
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))