Python/Tkinter列表框故障
我发布了一个问题,有人建议我重组代码。现在已经完全不同了,我觉得有理由问一个新问题 无论如何,我正在尝试向列表框添加拖放功能,但我认为一个好的第一步是首先让事件绑定工作。当前,当我单击列表时,单击列表框时会出现以下错误。此时会出现listbox窗口,但单击它时会出现错误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
"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))