组合框覆盖整个框

时间:2019-05-29 00:58:29

标签: python python-3.x tkinter

我正在编写一个脚本,可以搜索配方及其成分的列表。我想要一个类似google搜索框的东西,在键入时会给出一个下拉列表(这样用户可以看到成分并且没有错字)。我为此使用了组合框,但是我需要支持多种成分搜索,并且从组合框中进行选择会覆盖整个框(而不是部分框)。从组合框中选择时,我也无法键入。我可以使用任何命令来解决这些问题,还是必须覆盖脚本中的某些默认方法?如果是这样,请告诉我该怎么做。

我谦虚地接受我的代码的任何建议或批评。

感谢您抽出宝贵的时间阅读我的代码,并帮助我提出解决方案。

'__init__'包括窗口的所有内容,update_combo用于更新组合框的值,searchall和searchavailability只是该应用程序的功能,与上述问题无关。 count_drinks与上面的问题也不相关。

from collections import defaultdict
from tkinter.ttk import Combobox
from tkinter import *


class CapitalBartending:

    def __init__(self):
        self.mainwindow = Tk()
        self.mainwindow.maxsize(width=1100, height=800)
        self.mainwindow.title("Capital Bartending School")
        self.mainwindow.focus_set()

        self.searchframe = Frame(width=1000, height=180)
        self.resultframe = Frame()
        self.quitbutton = Frame()

        self.liquormsg1 = StringVar()
        self.liquormsg2 = StringVar()
        self.titlelabel = Label(self.searchframe, text="\nSearch Recipe", font=("", 20, "bold"))
        self.titlelabel.place(relx=0.5, rely=0.18, anchor=CENTER)
        # search and entry box
        self.searchlabel = Label(self.searchframe, text='Search: ')
        self.searchlabel.place(relx=0.36, rely=0.52, anchor=W)
        self.searchenter = Combobox(self.searchframe, width=60, postcommand=self.update_combo)
        self.searchenter.bind("<KeyRelease>", self.searchall)
        self.searchenter.place(relx=0.574, rely=0.52, anchor=CENTER)
        # availabile search and entry box
        self.availabilelabel = Label(self.searchframe, text='Available Liquor: ')
        self.availabilelabel.place(relx=0.314, rely=0.63, anchor=W)
        self.availabileenter = Combobox(self.searchframe, width=60, postcommand=self.update_combo)
        self.availabileenter.bind("<KeyRelease>", self.searchavailability)
        self.availabileenter.place(relx=0.574, rely=0.63, anchor=CENTER)
        # result label
        self.resultlabel = Label(self.searchframe, text='\nResults', font=("", 15))
        self.resultlabel.place(relx=0.499, rely=0.85, anchor=CENTER)
        # results
        self.showresult = Text(self.resultframe, font=("Calibri", 12), width=500)
        self.resultscroll = Scrollbar()
        self.showresult.pack(side='top')
        self.resultscroll.pack(side='right', fill=Y)
        self.resultscroll.config(command=self.showresult.yview)
        self.showresult.config(yscrollcommand=self.resultscroll.set)
        self.showresult.tag_config('center', justify='center')
        # destroy button
        self.end_button = Button(self.quitbutton, text='Quit', command=self.mainwindow.destroy, width=10)
        self.end_button.pack(side='bottom')
        # pack
        self.searchframe.pack(fill=X)
        self.resultframe.pack(expand=True)
        self.quitbutton.pack()
        # break until button
        self.mainwindow.mainloop()

    def searchall(self, event):
        self.showresult.delete(1.0, END)
        nameresultindex = [0] * 152
        alcoholresultindex = [1] * 152
        searchin = self.searchenter.get().lower().strip(",")
        if searchin == 'count_drinks()':
            self.count_drinks()
        for index, item in enumerate(name):
            if searchin.upper() in item:
                nameresultindex[index] = 1
        searchin = searchin.split(" ")
        if "" in searchin:
            searchin.pop()
        for i in range(len(searchin)):
            for j in range(len(procedure)):
                if searchin[i] not in procedure[j].lower():
                    alcoholresultindex[j] = 0
                if alcoholresultindex[j] == 1:
                    if searchin[i] not in procedure[j].lower():
                        alcoholresultindex[j] = 0
                else:
                    pass
        for i in range(len(nameresultindex)):
            if nameresultindex[i] == alcoholresultindex[i] == 1:
                alcoholresultindex[i] = 0
        if searchin:
            for i in range(len(nameresultindex)):
                if nameresultindex[i] == 1:
                    result = "\n" + name[i] + ': ' + procedure[i].replace("-", " ") + "\n"
                    self.showresult.insert(INSERT, result, 'center')
                if alcoholresultindex[i] == 1:
                    result = "\n" + name[i] + ': ' + procedure[i].replace("-", " ") + "\n"
                    self.showresult.insert(INSERT, result, 'center')

    def searchavailability(self, event):
        self.showresult.delete(1.0, END)
        resultindex = [0] * 152
        availabledrink = []
        availablenamein = self.availabileenter.get().title()
        availablenamein = availablenamein.split(",") if ',' in availablenamein else availablenamein.split(" ")
        if "" in availablenamein:
            availablenamein.pop()
        for item in availablenamein:
            for index, item2 in enumerate(used_alcohol):
                if item.replace(" ", "-") == item2.title():
                    availabledrink.append(index)
        availabledrink = list(set(availabledrink))
        for i in range(len(alcohol_in_drink)):
            for j in range(len(alcohol_in_drink[i])):
                if alcohol_in_drink[i][j] not in availabledrink:
                    break
                if alcohol_in_drink[i][j] == alcohol_in_drink[i][-1]:
                    resultindex[i] = 1
        if availabledrink:
            for index, item in enumerate(resultindex):
                if item == 1:
                    result = "\n" + name[index] + ': ' + procedure[index].replace("-", " ") + "\n"
                    self.showresult.insert(INSERT, result, 'center')

    def update_combo(self):
        # I want to update value list in combo box as user type in more characters
        suggestion = []
        # I have two combo box and need to get value from whichever one that's not empty
        suggestin = self.searchenter.get().title()
        suggestin = self.availabileenter.get().title() if suggestin == "" else suggestin
        # ',' is used when doing multi-ingredient search
        suggestin = suggestin.split(",") if ',' in suggestin else suggestin.split(" ")
        suggestin = [item.strip(' ') for item in suggestin]
        try:
            suggestin = suggestin.remove(" ")
        except ValueError:
            pass
        [suggestion.append(item) for item in used_alcohol if suggestin[-1] in item]
        suggestion.sort()
        self.searchenter['values'] = suggestion
        print(suggestion, suggestin)

    def count_drinks(self):
        not_liquor = ['Shake', 'Juice', 'Mix', 'Sour', 'Cream', 'Soda', 'Melon', 'Liqueur', 'Cherry', 'Water', 'Sugar',
                      'Dark', 'Light', 'Salt', 'Coke', 'Ginger', 'Red', 'Bull', 'Orange']
        count_liquors = defaultdict(lambda: 0)
        for item in procedure:
            line = item.replace(',', '').replace("'", '').replace('(', '').replace(')', '').replace('=', '').split(' ')
            for item1 in line:
                count_liquors[item1] += 1 if item1.istitle() and item1 not in not_liquor else 0
        count_liquors = [(key, count_liquors[key]) for key in count_liquors.keys()]
        count_liquors.sort(key=lambda item: item[1], reverse=True)
        while True:
            if 0 in count_liquors[-1]:
                count_liquors.pop()
            else:
                break
        with open('used_alcohol_ver_2.txt', 'w') as outfile:
            [outfile.write(item[0] + ' ' + str(item[1]) + '\n') for item in count_liquors]


if __name__ == '__main__':
    with open('recipe.txt', 'r') as filein:
        recipein = filein.read().split('\n')
    with open('used_alcohol.txt', 'r') as filein:
        alcoholin = filein.read().split('\n')
    name = []
    procedure = []
    used_alcohol = []
    alcohol_in_drink = []
    # construct name and procedure list
    [(name.append(item[:item.index('|')]), procedure.append(item[item.index('|') + 1:])) for item in recipein]
    [used_alcohol.append(item.split(' ')[0]) for item in alcoholin]
    # construct a list for alcohol used in each recipe
    for index, item in enumerate(procedure):
        line = item.replace(",", "").split(" ")
        alcohol_in_drink.append([])
        for index2, item2 in enumerate(used_alcohol):
            if item2 in line:
                alcohol_in_drink[index].append(index2)

    CapitalBartending()

0 个答案:

没有答案