【问题标题】:Tkinter autocomplete: How to pass selected value to another classTkinter 自动完成:如何将选定的值传递给另一个类
【发布时间】:2015-12-03 00:23:01
【问题描述】:

我有一个带有组合框和列表框的简单 GUI,它依赖于组合框。列表框具有自动完成功能。现在我想将组合框的选择以及列表框的选择传递给一个函数。这是我到目前为止的代码:

from Tkinter import *
import ttk, os, re
root = Tk()
root.minsize(500,300)
root.maxsize(550,310)

def go(Arg1, Arg2):
    print "works" + Arg1 + Arg2


class AutocompleteEntry(Entry):
    def __init__(self, lista, *args, **kwargs):
        Entry.__init__(self, *args, **kwargs)
        self.lista = lista
        self.var = self["textvariable"]
        if self.var == '':
            self.var = self["textvariable"] = StringVar()
        self.var.trace('w', self.changed)
        self.bind("<Right>", self.selection)
        self.bind("<Up>", self.up)
        self.bind("<Down>", self.down)
        self.lb_up = False


    def changed(self, name, index, mode):
        if self.var.get() == '':
            self.lb.destroy()
            self.lb_up = False
        else:
            words = self.comparison()
            print words
            if words:
                if not self.lb_up:
                    self.lb = Listbox()
                    self.lb.bind("<Double-Button-1>", self.selection)
                    self.lb.bind("<Right>", self.selection)
                    self.lb.place(x=self.winfo_x(), y=self.winfo_y()+self.winfo_height())
                    self.lb_up = True

                self.lb.delete(0, END)
                for w in words:
                    self.lb.insert(END,w)
            else:
                if self.lb_up:
                    self.lb.destroy()
                    self.lb_up = False

    def selection(self, event):
        if self.lb_up:
            self.var.set(self.lb.get(ACTIVE))
            self.list_out = self.lb.get(ACTIVE)

            self.lb.destroy()
            self.lb_up = False
            self.icursor(END)
        return self.list_out

    def up(self, event):
        if self.lb_up:
            if self.lb.curselection() == ():
                index = '0'
            else:
                index = self.lb.curselection()[0]
            if index != '0':
                self.lb.selection_clear(first=index)
                index = str(int(index)-1)
                self.lb.selection_set(first=index)
                self.lb.activate(index)

    def down(self, event):
        if self.lb_up:
            if self.lb.curselection() == ():
                index = '0'
            else:
                index = self.lb.curselection()[0]
            if index != END:
                self.lb.selection_clear(first=index)
                index = str(int(index)+1)
                self.lb.selection_set(first=index)
                self.lb.activate(index)

    def comparison(self):
        pattern = re.compile(self.var.get() + '.*')
        return [w for w in self.lista if re.match(pattern, w)]




class MyListbox:

    lista = ['a', 'actions', 'additional', 'also', 'an', 'and', 'angle', 'are', 'as', 'be', 'bind', 'bracket', 'brackets', 'button', 'can', 'cases', 'configure', 'course', 'detail', 'enter', 'event', 'events', 'example', 'field', 'fields', 'for', 'give', 'important', 'in', 'information', 'is', 'it', 'just', 'key', 'keyboard', 'kind', 'leave', 'left', 'like', 'manager', 'many', 'match', 'modifier', 'most', 'of', 'or', 'others', 'out', 'part', 'simplify', 'space', 'specifier', 'specifies', 'string;', 'that', 'the', 'there', 'to', 'type', 'unless', 'use', 'used', 'user', 'various', 'ways', 'we', 'window', 'wish', 'you']


    def __init__(self, parent, title):
        self.parent = parent
        self.parent.title(title)
        self.parent.protocol("WM_DELETE_WINDOW", self.closes)
        self.cities = ['New York', 'Vienna', 'Miami', 'Oslo']

        self.establishment()

    def combobox_handler(self, event):
        current = self.combobox.current()
        print self.combobox.get()
        self.combo_out = self.combobox.get()
        self.entNumber.delete(0, END)

        print self.lista
        self.entNumber.delete(0, END)
        self.entNumber = AutocompleteEntry(self.lista, self.parent)
        self.entNumber.place(x=50, y=100)
        return self.combo_out



    def establishment(self):
        mainFrame = Frame(self.parent)
        mainFrame.pack(fill=BOTH, expand=YES)

        fr_left = Frame(mainFrame, bd=10)
        fr_left.pack(fill=BOTH, expand=YES, side=LEFT)

        self.combobox = ttk.Combobox(fr_left, values=self.cities)
        self.combobox.bind('<<ComboboxSelected>>', self.combobox_handler)
        self.combobox.pack()

        fr_right = Frame(mainFrame, bd=10)
        fr_right.pack(fill=BOTH, expand=YES, side=RIGHT)

        fr_up = Frame(fr_right)
        fr_up.pack(side=TOP, expand=YES)


        self.entNumber = Entry()
        self.entNumber.place(x=50, y=100)
        labb=Button(fr_left,text="OK",command= lambda: go(self.combo_out, AutocompleteEntry.list_out), bg="green")
        labb.pack(side=BOTTOM, fill=X, pady=5)


    def closes(self, event=None):
        self.parent.destroy()

if __name__ == '__main__':
    app = MyListbox(root, "Main Window")
    root.mainloop()

传递组合框的变量不是问题,但传递列表框的变量对我来说很棘手,因为它来自不同的类。这是选择列表框的部分,我想通过list_out

def selection(self, event):
    if self.lb_up:
        self.var.set(self.lb.get(ACTIVE))
        self.list_out = self.lb.get(ACTIVE)

        self.lb.destroy()
        self.lb_up = False
        self.icursor(END)
    return self.list_out

代码在复制到您的系统时有效。

【问题讨论】:

  • 您的问题不清楚。您写道“我想将组合框的选择以及列表框的选择传递给函数”。您想在代码的哪个位置执行此操作?
  • 使用按钮“labb”我尝试将 2 个变量 combo_out 和 list_out 传递给函数 go()

标签: python combobox autocomplete tkinter listbox


【解决方案1】:

首先,不要使用lambdalambda 在真正需要时很有用,但在这种情况下它不是。它所做的只是增加代码的复杂性。一个好的经验法则是永远不要使用 lambda,直到没有其他选择。

其次,让按钮调用属于类的函数。您需要的数据已经可以访问,因此根本不需要传递它。

类 MyListbox: ... def go(self): 打印“作品”+ self.combo_out,self.entNumber.list_out ... def 建立(自我): ... labb=Button(fr_left,text="OK",command= self.go)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多