Python tkinter Multilistbox自定义事件绑定问题
所以我的项目是关于显示数据库中的信息和图像。 其思路如下: 我有一个描述图像的数据库。一个表具有一般信息,如图像中包含的颜色,另一个表具有更详细的信息,如在何处可以找到该颜色,等等 启动搜索时,我希望打开两个窗口(Python tkinter Multilistbox自定义事件绑定问题,python,tkinter,listbox,Python,Tkinter,Listbox,所以我的项目是关于显示数据库中的信息和图像。 其思路如下: 我有一个描述图像的数据库。一个表具有一般信息,如图像中包含的颜色,另一个表具有更详细的信息,如在何处可以找到该颜色,等等 启动搜索时,我希望打开两个窗口(ClassTwo和ClassTwo)。 与第一个只包含启动搜索按钮的窗口不同,我的完整应用程序包含用于筛选数据库请求的字段。当我启动该搜索时,我希望所有图像中都有绿色,因此ClassTwo将列出所有具有该颜色的图像以及其他元数据 ClassThree然后会列出所有包含相同颜色的区域,但
ClassTwo
和ClassTwo
)。
与第一个只包含启动搜索按钮的窗口不同,我的完整应用程序包含用于筛选数据库请求的字段。当我启动该搜索时,我希望所有图像中都有绿色,因此ClassTwo
将列出所有具有该颜色的图像以及其他元数据
ClassThree
然后会列出所有包含相同颜色的区域,但要更加详细,比如图像中的位置和大小等。
单击任一多列表框
,我想打开一个显示图像的ImageViewer。
对于ClassThree
,我还将直接突出显示我单击的区域,这样两个类都将有绑定到多列表框的函数
我的问题是列表框的绑定不正常。当我使用例如image\u parts\u info\u lb.bind()
时,根本不会触发该函数。使用image\u parts\u info\u lb.bind\u all()
时,仅触发最后一个多列表框的功能
您可以在类的注释中找到MultiListbox
的原始Python2
版本
这是我的密码
import tkinter as tk
class MultiListbox(tk.Frame):
#original Python2 code here:
#https://www.oreilly.com/library/view/python-cookbook/0596001673/ch09s05.html
def __init__(self, master, lists):
tk.Frame.__init__(self, master)
self.lists = []
print(lists)
for l,w in lists:
frame = tk.Frame(self)
frame.pack(side='left', expand='yes', fill='both')
tk.Label(frame, text=l, borderwidth=1, relief='raised').pack(fill='x')
lb = tk.Listbox(frame, width=w, borderwidth=0, selectborderwidth=0,
relief='flat', exportselection=False, height=16)
lb.pack(expand='yes', fill='both')
self.lists.append(lb)
#commented out functions that were not necessary, as suggested in the comments
#lb.bind('<B1-Motion>', self._select)
lb.bind('<<ListboxSelect>>', self._select)
#lb.bind('<Leave>', lambda e: 'break')
lb.bind('<MouseWheel>', lambda e, s=self: s._scroll_mouse(e))
#lb.bind('<Button-2>', lambda e, s=self: s._button2(e.x, e.y))
frame = tk.Frame(self)
frame.pack(side='left', fill='y')
tk.Label(frame, borderwidth=1, relief='raised').pack(fill='x')
sb = tk.Scrollbar(frame, orient='vertical', command=self._scroll)
sb.pack(expand='yes', fill='y')
self.lists[0]['yscrollcommand']=sb.set
def _select(self, event):
w = event.widget
curselection = w.curselection()
if curselection:
self.selection_clear(0, self.size())
self.selection_set(curselection[0])
def _button2(self, x, y):
for l in self.lists:
l.scan_mark(x, y)
return 'break'
def _b2motion(self, x, y):
for l in self.lists: l.scan_dragto(x, y)
return 'break'
def _scroll(self, *args):
for l in self.lists:
l.yview(*args)
return 'break'
def _scroll_mouse(self, event):
for l in self.lists:
l.yview_scroll(int(-1*(event.delta/120)), 'units')
return 'break'
def curselection(self):
return self.lists[0].curselection()
def delete(self, first, last=None):
for l in self.lists:
l.delete(first, last)
def get(self, first, last=None):
result = []
for l in self.lists:
result.append(l.get(first,last))
if last: return apply(map, [None] + result)
return result
def index(self, index):
self.lists[0].index(index)
def insert(self, index, *elements):
for e in elements:
for i, l in enumerate(self.lists):
l.insert(index, e[i])
def size(self):
return self.lists[0].size()
def see(self, index):
for l in self.lists:
l.see(index)
def selection_anchor(self, index):
for l in self.lists:
l.selection_anchor(index)
def selection_clear(self, first, last=None):
for l in self.lists:
l.selection_clear(first, last)
def selection_includes(self, index):
return self.lists[0].selection_includes(index)
def selection_set(self, first, last=None):
for l in self.lists:
l.selection_set(first, last)
class ClassOne:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
self.create_elements()
self.frame.pack()
def create_elements(self):
search_button = tk.Button(self.frame, text = "Launch searches", command = \
self.call_other_classes)
search_button.grid(row = 2, column = 0, padx = 20, pady = 10)
exit_button = tk.Button(self.frame, text = "Exit", command = self.master.quit)
exit_button.grid(row = 2, column = 1, padx = 20, pady = 10)
def call_other_classes(self):
self.classes_list = []
self.classes_list.append(ClassTwo(self.master))
self.classes_list.append(ClassThree(self.master))
class ClassTwo:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(tk.Toplevel(self.master))
self.frame.pack()
self.create_elements()
self.fill_image_listbox()
def create_elements(self):
#placement of the custom MultiListbox
self.available_images_lb = MultiListbox(self.frame, (('stuff1', 0), ('stuff1', 0), \
('stuff1', 0), ('stuff1', 0), ('stuff1', 0) ))
self.available_images_lb.grid(row = 1, column = 1)
self.available_images_lb.bind('<<ListboxSelect>>', self.print_stuff_two)
#Button
exit_button = tk.Button(self.frame, text = "Quit", command = self.frame.quit)
exit_button.grid(row = 2, column = 1, padx = 20, pady = 10)
def fill_image_listbox(self):
image_info = [5*['ABCD'],5*['EFGH'],5*['JKLM'],5*['NOPQ'],5*['RSTU'], 5*['VWXY']]
for item in image_info:
self.available_images_lb.insert('end', item)
def print_stuff_two(self, event):
print('Class Two active')
class ClassThree:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(tk.Toplevel(self.master))
self.create_elements()
self.frame.pack()
self.fill_imageparts_listbox()
def create_elements(self):
self.image_parts_info_lb = MultiListbox(self.frame, (('stuff1', 0), ('stuff1', 0), \
('stuff1', 0), ('stuff1', 0), ('stuff1', 0) ))
self.image_parts_info_lb.grid(row = 1, column = 1)
self.image_parts_info_lb.bind('<<ListboxSelect>>', self.print_stuff_three)
def fill_imageparts_listbox(self):
self.image_parts_info_lb.delete(0, 'end')
image_part_info = [5*['1234'],5*['5678'],5*['91011']]
for item in image_part_info:
self.image_parts_info_lb.insert('end', item)
def print_stuff_three(self, event):
print('Class Three active')
def main():
root = tk.Tk()
root.title('Image Viewer')
root.geometry('500x150+300+300')
my_class_one = ClassOne(root)
root.mainloop()
if __name__ == "__main__":
main()
将tkinter作为tk导入
类MultiListbox(tk.Frame):
#原始Python2代码如下:
#https://www.oreilly.com/library/view/python-cookbook/0596001673/ch09s05.html
定义初始化(自、主、列表):
tk.Frame.\uuuuu init\uuuuuuu(自,主)
self.lists=[]
打印(列表)
对于列表中的l、w:
框架=传统框架(自身)
frame.pack(side='left',expand='yes',fill='both')
tk.Label(frame,text=l,borderwidth=1,relief='raised').pack(fill='x'))
lb=tk.Listbox(边框,宽度=w,边框宽度=0,选择边框宽度=0,
浮雕=平,导出选择=假,高度=16)
lb.pack(扩展class='yes',填充class='both')
self.lists.append(lb)
#按照注释中的建议,注释掉了不必要的函数
#lb.bind(“”,self.\u选择)
lb.bind(“”,self.\u选择)
#lb.bind('',lambda e:'断裂')
lb.bind(“”,lambda e,s=self:s._滚动_鼠标(e))
#lb.bind(“”,λe,s=自身:s._按钮2(e.x,e.y))
框架=传统框架(自身)
框架包装(侧面为左,填充为y)
tk.标签(边框,边框宽度=1,浮雕='凸起').pack(填充='x')
sb=tk.滚动条(框架,方向=垂直,命令=自滚动)
某人打包(扩展为“是”,填充为“y”)
self.lists[0]['yscrollcommand']=sb.set
def_选择(自身、事件):
w=事件.widget
curselection=w.curselection()
如果选择:
self.selection\u clear(0,self.size())
自选择集(选择[0])
def_按钮2(自身、x、y):
对于self.List中的l:
l、 扫描标记(x,y)
返回“中断”
def_b2运动(自、x、y):
对于self.list中的l:l.scan_dragto(x,y)
返回“中断”
def_滚动(自,*args):
对于self.List中的l:
l、 yview(*args)
返回“中断”
定义滚动鼠标(自身,事件):
对于self.List中的l:
l、 Y视图滚动(int(-1*(event.delta/120)),“单位”)
返回“中断”
选举(自选):
返回self.lists[0].curselection()
def delete(自我、第一、最后=无):
对于self.List中的l:
l、 删除(第一个,最后一个)
def get(自我、第一、最后=无):
结果=[]
对于self.List中的l:
result.append(l.get(first,last))
如果最后一个:返回应用(映射,[无]+结果)
返回结果
def索引(自我,索引):
self.lists[0]。索引(index)
def插入(自、索引、*元素):
对于元素中的e:
对于枚举(自我列表)中的i,l:
l、 插入(索引,e[i])
def大小(自身):
返回self.lists[0].size()
def见(自我,索引):
对于self.List中的l:
l、 见(索引)
def选择_锚(自身,索引):
对于self.List中的l:
l、 选择锚(索引)
def选择_清除(自身、第一个、最后一个=无):
对于self.List中的l:
l、 选择\u清除(第一个、最后一个)
def选择_包括(自身、索引):
返回self.lists[0]。选择内容包括(索引)
def选择_设置(自身、第一个、最后一个=无):
对于self.List中的l:
l、 选择集(第一个、最后一个)
一级:
定义初始(自我,主):
self.master=master
self.frame=tk.frame(self.master)
self.create_元素()
self.frame.pack()
def创建_元素(自):
搜索按钮=tk.按钮(self.frame,text=“启动搜索”,命令=\
self.call_其他_类)
搜索按钮网格(行=2,列=0,padx=20,pady=10)
退出按钮=tk.button(self.frame,text=“exit”,command=self.master.quit)
退出按钮网格(行=2,列=1,padx=20,pady=10)
def调用其他类(自身):
self.classes_list=[]
self.classes\u list.append(ClassTwo(self.master))
self.classes\u list.append(ClassThree(self.master))
第二类:
定义初始(自我,主):
self.master=master
self.frame=tk.frame(tk.top-level(self.master))
self.frame.pack()
self.create_元素()
self.fill\u image\u listbox()
def创建_元素(自):
#自定义Mu的放置
self.event_generate('<<MultiListboxSelect>>', when='tail')
class MultiListbox(tk.Frame):
def __init__(self, master, lists):
...
for l,w in lists:
...
lb = tk.Listbox(frame, ...
lb.bind('<<ListboxSelect>>', self._select)
def _select(self, event):
w = event.widget
curselection = w.curselection()
if curselection:
self.event_generate('<<MultiListboxSelect>>', when='tail')
...
class ClassTwo:
...
def create_elements(self):
self.available_images_lb = MultiListbox(self.frame, ...
...
self.available_images_lb.bind('<<MultiListboxSelect>>', self.print_stuff_two)
...
class ClassThree:
...
def create_elements(self):
self.image_parts_info_lb = MultiListbox(self.frame, ...
...
self.image_parts_info_lb.bind('<<MultiListboxSelect>>', self.print_stuff_three)