从Python 3.5中的不同Tkinter列表框小部件中同时选择值 [英] Selecting values simultaneously from different Tkinter Listbox widgets in Python 3.5

查看:67
本文介绍了从Python 3.5中的不同Tkinter列表框小部件中同时选择值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我的程序以下列方式工作:

  • 当我从3个列表框中的任意一个单击元素以选择相邻的值时(例如:如果我在第一个列表框中选择0,则应该在第二个列表框中选择值"hello",在第三个列表中选择值"world")列表框

感谢此问题/答案我设法使它们同时移动

代码如下:

from tkinter import *

class fase3(Frame):

    def __init__(self, master):


        Frame.__init__(self,master)
        self.master=master
        self.frame=Frame(self.master)

        self.txtm=Label(self, text="example")
        self.txtm.grid(row=1, columnspan=5)

        self.txt1=Label(self, text="1")
        self.txt1.grid(row=2, column=1)

        self.txt2=Label(self, text="2")
        self.txt2.grid(row=2,column=2)

        self.txt3=Label(self, text="3")
        self.txt3.grid(row=2,column=3)
        self.scrlb=Scrollbar(self,orient="vertical")

        self.lista1=Listbox(self,yscrollcommand=self.yscroll1,exportselection=0)
        self.lista1.grid(row=3,column=1)

        self.lista2=Listbox(self, yscrollcommand=self.yscroll2,exportselection=0)
        self.lista2.grid(row=3, column=2)

        self.lista3=Listbox(self, yscrollcommand=self.yscroll3,exportselection=0)
        self.lista3.grid(row=3, column=3)

        #self.scrlb.config(command=self.yview)
        #self.scrlb.grid(row=3, column=4,rowspan=1)
#i chose not to place the scrollbar because it involved frames and it makes the code longer


        for i in range(3):
            self.lista1.insert("end",i)

        self.lista2.insert("end","hello")
        self.lista2.insert("end","pls")
        self.lista2.insert("end","thanks")
        self.lista3.insert("end","world")
        self.lista3.insert("end","help")
        self.lista3.insert("end","alot")

    def yscroll1(self, *args):
        if  self.lista2.yview()!=self.lista1.yview()!=self.lista3.yview():
            self.lista2.yview_moveto(args[0])
            self.lista3.yview_moveto(args[0])
        self.scrlb.set(*args)

    def yscroll2(self, *args):
        if  self.lista1.yview()!=self.lista2.yview()!=self.lista1.yview():
            self.lista1.yview_moveto(args[0])
            self.lista3.yview_moveto(args[0])
        self.scrlb.set(*args)

    def yscroll3(self, *args):
        if self.lista2.yview()!=self.lista3.yview()!=self.lista1.yview():
            self.lista1.yview_moveto(args[0])
            self.lista2.yview_moveto(args[0])
        self.scrlb.set(*args)

    def yview(self, *args):
        self.lista1.yview(*args)
        self.lista2.yview(*args)
        self.lista3.yview(*args)



    self.pack()

root = Tk()

marco= Frame(root, padx=100, pady=50)

marco.pack()

lf = fase3(marco)

root.mainloop()

问题的一部分是,我已经有一个绑定到每个列表框的函数,当我添加exportselection=0时,它选择一个值,因此,例如,用户可以选择("0","hello",很多"),对我而言,这根本没有任何意义(插入数据库)

我还没有进行任何处理,但是如果他们可以同时移动,那么他们应该可以选择相邻的值.

您应该能够复制粘贴此代码并在Python上运行它,而没有问题,我是在python 3中创建的.

解决方案

要做的第一件事是绑定到<<ListboxSelect>>事件,以检测何时在一个列表框中选择了一个选项:

def __init__(self, master):

    # ...

    self.lista1=Listbox(self,yscrollcommand=self.yscroll1,exportselection=0)
    self.lista1.bind('<<ListboxSelect>>', self.on_select1)
    self.lista1.grid(row=3,column=1)

    self.lista2=Listbox(self, yscrollcommand=self.yscroll2,exportselection=0)
    self.lista2.bind('<<ListboxSelect>>', self.on_select2)
    self.lista2.grid(row=3, column=2)

    self.lista3=Listbox(self, yscrollcommand=self.yscroll3,exportselection=0)
    self.lista3.bind('<<ListboxSelect>>', self.on_select3)
    self.lista3.grid(row=3, column=3)

     # ...

选择一个选项后,您要在其他列表框中选择相应的选项:

def on_select1(self, event):
    # Get index of selected option.
    index = self.lista1.curselection()[0]
    # Select corresponding options in other list-boxes.
    self.select_others(index, self.lista2, self.lista3)

def on_select2(self, event):
    # Get index of selected option.
    index = self.lista2.curselection()[0]
    # Select corresponding options in other list-boxes.
    self.select_others(index, self.lista1, self.lista3)

def on_select3(self, event):
    # Get index of selected option.
    index = self.lista3.curselection()[0]
    # Select corresponding options in other list-boxes.
    self.select_others(index, self.lista1, self.lista2)

def select_others(self, index, *others):
    for listbox in others:
        # The list-box's selection must be cleared to prevent the previous selection from remaining.
        listbox.selection_clear(0, listbox.size() - 1)
        listbox.selection_set(index)

最后,在face3类末尾的self.pack()放错了位置.

class face3(Frame):

    # ...

    self.pack()

您应该打包lf:

root = Tk()

marco = Frame(root, padx=100, pady=50)
marco.pack()

lf = fase3(marco)
lf.pack()

root.mainloop()

I want my program to work in a way that:

  • when I click an element from either of the 3 listboxes to select the adjacent values (example: if i select 0 in the first listbox, it should select the value "hello" in the second listbox and "world" in the third listbox

Thanks to This question/answer I managed to make them move simultaneously

the code is the following:

from tkinter import *

class fase3(Frame):

    def __init__(self, master):


        Frame.__init__(self,master)
        self.master=master
        self.frame=Frame(self.master)

        self.txtm=Label(self, text="example")
        self.txtm.grid(row=1, columnspan=5)

        self.txt1=Label(self, text="1")
        self.txt1.grid(row=2, column=1)

        self.txt2=Label(self, text="2")
        self.txt2.grid(row=2,column=2)

        self.txt3=Label(self, text="3")
        self.txt3.grid(row=2,column=3)
        self.scrlb=Scrollbar(self,orient="vertical")

        self.lista1=Listbox(self,yscrollcommand=self.yscroll1,exportselection=0)
        self.lista1.grid(row=3,column=1)

        self.lista2=Listbox(self, yscrollcommand=self.yscroll2,exportselection=0)
        self.lista2.grid(row=3, column=2)

        self.lista3=Listbox(self, yscrollcommand=self.yscroll3,exportselection=0)
        self.lista3.grid(row=3, column=3)

        #self.scrlb.config(command=self.yview)
        #self.scrlb.grid(row=3, column=4,rowspan=1)
#i chose not to place the scrollbar because it involved frames and it makes the code longer


        for i in range(3):
            self.lista1.insert("end",i)

        self.lista2.insert("end","hello")
        self.lista2.insert("end","pls")
        self.lista2.insert("end","thanks")
        self.lista3.insert("end","world")
        self.lista3.insert("end","help")
        self.lista3.insert("end","alot")

    def yscroll1(self, *args):
        if  self.lista2.yview()!=self.lista1.yview()!=self.lista3.yview():
            self.lista2.yview_moveto(args[0])
            self.lista3.yview_moveto(args[0])
        self.scrlb.set(*args)

    def yscroll2(self, *args):
        if  self.lista1.yview()!=self.lista2.yview()!=self.lista1.yview():
            self.lista1.yview_moveto(args[0])
            self.lista3.yview_moveto(args[0])
        self.scrlb.set(*args)

    def yscroll3(self, *args):
        if self.lista2.yview()!=self.lista3.yview()!=self.lista1.yview():
            self.lista1.yview_moveto(args[0])
            self.lista2.yview_moveto(args[0])
        self.scrlb.set(*args)

    def yview(self, *args):
        self.lista1.yview(*args)
        self.lista2.yview(*args)
        self.lista3.yview(*args)



    self.pack()

root = Tk()

marco= Frame(root, padx=100, pady=50)

marco.pack()

lf = fase3(marco)

root.mainloop()

part of the problem is, I already have a function bound to every Listbox, when I add exportselection=0, it selects a single value, so, for example the user can select ("0","hello","alot"), which for my purposes would make no sense at all (insertion to a database)

I haven't made any process in this, but if its possible for them to move simultaneously, it should somehow be possible for them to select adjacent values.

you should be able to copy paste this and run it on Python without a problem, I made it in python 3.

解决方案

The first thing you want to do is bind to the <<ListboxSelect>> event to detect when an option is selected in one of your list-boxes:

def __init__(self, master):

    # ...

    self.lista1=Listbox(self,yscrollcommand=self.yscroll1,exportselection=0)
    self.lista1.bind('<<ListboxSelect>>', self.on_select1)
    self.lista1.grid(row=3,column=1)

    self.lista2=Listbox(self, yscrollcommand=self.yscroll2,exportselection=0)
    self.lista2.bind('<<ListboxSelect>>', self.on_select2)
    self.lista2.grid(row=3, column=2)

    self.lista3=Listbox(self, yscrollcommand=self.yscroll3,exportselection=0)
    self.lista3.bind('<<ListboxSelect>>', self.on_select3)
    self.lista3.grid(row=3, column=3)

     # ...

When an option is selected, you want to select the corresponding option in the other list-boxes:

def on_select1(self, event):
    # Get index of selected option.
    index = self.lista1.curselection()[0]
    # Select corresponding options in other list-boxes.
    self.select_others(index, self.lista2, self.lista3)

def on_select2(self, event):
    # Get index of selected option.
    index = self.lista2.curselection()[0]
    # Select corresponding options in other list-boxes.
    self.select_others(index, self.lista1, self.lista3)

def on_select3(self, event):
    # Get index of selected option.
    index = self.lista3.curselection()[0]
    # Select corresponding options in other list-boxes.
    self.select_others(index, self.lista1, self.lista2)

def select_others(self, index, *others):
    for listbox in others:
        # The list-box's selection must be cleared to prevent the previous selection from remaining.
        listbox.selection_clear(0, listbox.size() - 1)
        listbox.selection_set(index)

Finally, the self.pack() at the end of the face3 class is misplaced.

class face3(Frame):

    # ...

    self.pack()

You should pack lf instead:

root = Tk()

marco = Frame(root, padx=100, pady=50)
marco.pack()

lf = fase3(marco)
lf.pack()

root.mainloop()

这篇关于从Python 3.5中的不同Tkinter列表框小部件中同时选择值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆