简体   繁体   English

如何使用 Python 中的 Tkinter 使按钮仅单击一次?

[英]How to make buttons to be only clicked once using Tkinter in Python?

So I made a sill calculator that just takes an input of 'banana' and 'milk' when the user does such calculation: banana + milk, then it returns 'banana milk' and so on.所以我做了一个窗台计算器,当用户进行这样的计算时,它只输入“香蕉”和“牛奶”:香蕉+牛奶,然后它返回“香蕉牛奶”等等。 Since these strings are not a number, I want the buttons to be only clickable once so that it will never be 'banana banana + milk' but only 'banana + milk' or 'milk + banana'...由于这些字符串不是数字,我希望按钮只能点击一次,这样它就不会是“香蕉香蕉+牛奶”,而只有“香蕉+牛奶”或“牛奶+香蕉”......

Also, whenever the user puts only one input such as 'banana' and press Enter (finalPress), I want to print out only 'banana', but with my code, it goes to elif phrase[0] == 'Banana': and prints out 'banana milk' even though I only press 'banana'.此外,每当用户只输入一个输入,例如“香蕉”并按 Enter(finalPress)时,我只想打印“香蕉”,但使用我的代码,它会转到elif 短语 [0] == '香蕉':并打印出“香蕉牛奶”,即使我只按“香蕉”。 How can I fix this issue?我该如何解决这个问题?

Below is my code:下面是我的代码:

from tkinter import *

phrase = []
phrase_string = ''


# To press any button
def press(item):
    global phrase, phrase_string
    if item == 'Banana':
        phrase.append('Banana')
    elif item == 'Milk':
        phrase.append('Milk')
    elif item == 'AND':
        phrase.append(' and ')

    phrase_string = ''
    for ele in phrase:
        phrase_string += ele
    return equation.set(phrase_string)


# This is enter
def finalPress():
    global phrase, phrase_string
    if phrase[0] in ['Banana', 'Milk'] and len(phrase) is 1:
        phrase = phrase[0]
    elif phrase[0] == 'Banana':
        if phrase[1] == ' and ':
            phrase.clear()
            phrase = 'Banana Milk'
    elif phrase[0] == 'Milk':
        if phrase[1] == ' and ':
            phrase.clear()
            phrase = 'Milk Banana'

    return equation.set(phrase)


# Clear the content
def clearContent():
    pass


# Driver code
if __name__ == '__main__':
    # create application window
    app = Tk()

    # title
    app.title("Slly Calculator")

    # geometry
    app.geometry('290x162')

    # background color
    app.configure(bg='pink')

    equation = StringVar()
    windows = Entry(app, textvariable=equation)
    windows.grid(columnspan=5, ipadx=100, ipady=10)
    equation.set('Press Buttons Please')

    # Create buttons and other accessories
    button1 = Button(app, text=' Banana ', fg='yellow', bg='purple',
                     command=lambda: press('Banana'), height=2, width=10)
    button1.grid(row=2, column=0, sticky="NSEW")

    button2 = Button(app, text=' Milk ', fg='brown', bg='pink',
                     command=lambda: press('Milk'), height=2, width=10)
    button2.grid(row=2, column=1, sticky="NSEW")

    plus = Button(app, text='AND', fg='black', bg='white',
                  command=lambda: press('AND'), height=2, width=10)
    plus.grid(row=4, column=0, sticky="NSEW")

    equal = Button(app, text='ENTER', fg='black', bg='white',
                   command=finalPress, height=2, width=10)
    equal.grid(row=4, column=2, sticky="NSEW")

# start the GUI
app.mainloop()

Thank you so much: :-D非常感谢:-D

I didn't take a look on function of "enter" button, because I'm not really sure, what it's suppose to do.我没有看“输入”按钮的 function,因为我不太确定它应该做什么。 I changed only this:我只改变了这个:

from tkinter import *

phrase = []
phrase_string = ''
words_product = ['Banana', 'Milk']
words_conjunction = [" and "]


# To press any button
def press(item):
    global phrase, phrase_string

    # len(phrase) != 0 - don't allow to write 'and' when nothing was pressed before to avoid i.e. 'and banana milk'
    # item not in phrase - to avoid writing product more then one time to avoid banana and milkmilk or bananabanana

    if item in words_product:
        if all([item not in phrase]):
            phrase.append(item)
    elif item in words_conjunction:
        if all([len(phrase) != 0, item not in phrase]):   # if you want want allow to banana and milk and something
            phrase.append(item)                           # delete ' item not in phrase"

    phrase_string = ''

    for ele in phrase:
        phrase_string += ele
    return equation.set(phrase_string)

And this:和这个:

plus = Button(app, text='AND', fg='black', bg='white',
              command=lambda: press(" and "), height=2, width=10)

So the full code is:所以完整的代码是:

from tkinter import *

phrase = []
phrase_string = ''
words_product = ['Banana', 'Milk']
words_conjunction = [" and "]


# To press any button
def press(item):
    global phrase, phrase_string

    # len(phrase) != 0 - don't allow to write 'and' when nothing was pressed before to avoid i.e. 'and banana milk'
    # item not in phrase - to avoid writing product more then one time to avoid banana and milkmilk or bananabanana

    if item in words_product:
        if all([item not in phrase]):
            phrase.append(item)
    elif item in words_conjunction:
        if all([len(phrase) != 0, item not in phrase]):   # if you want want allow to banana and milk and something
            phrase.append(item)                           # delete ' item not in phrase"

    phrase_string = ''

    for ele in phrase:
        phrase_string += ele
    return equation.set(phrase_string)


# This is enter
def finalPress():
    global phrase, phrase_string
    if phrase[0] in ['Banana', 'Milk'] and len(phrase) == 1:
        phrase_string = phrase[0]
    elif phrase[0] == 'Banana' and phrase[1] == " and ":
        phrase.clear()
        phrase = 'Banana Milk'

    elif phrase[0] == 'Milk' and phrase[1] == " and ":
        phrase.clear()
        phrase = 'Milk Banana'

    return equation.set(phrase)


# Clear the content
def clearContent():
    pass


# Driver code
if __name__ == '__main__':
    # create application window
    app = Tk()

    # title
    app.title("Slly Calculator")

    # geometry
    app.geometry('290x162')

    # background color
    app.configure(bg='pink')

    equation = StringVar()
    windows = Entry(app, textvariable=equation)
    windows.grid(columnspan=5, ipadx=100, ipady=10)
    equation.set('Press Buttons Please')

    # Create buttons and other accessories
    button1 = Button(app, text=' Banana ', fg='yellow', bg='purple',
                     command=lambda: press('Banana'), height=2, width=10)
    button1.grid(row=2, column=0, sticky="NSEW")

    button2 = Button(app, text=' Milk ', fg='brown', bg='pink',
                     command=lambda: press('Milk'), height=2, width=10)
    button2.grid(row=2, column=1, sticky="NSEW")

    plus = Button(app, text='AND', fg='black', bg='white',
                  command=lambda: press(" and "), height=2, width=10)
    plus.grid(row=4, column=0, sticky="NSEW")

    equal = Button(app, text='ENTER', fg='black', bg='white',
                   command=finalPress, height=2, width=10)
    equal.grid(row=4, column=2, sticky="NSEW")

    # start the GUI
    app.mainloop()

I decided it's a good idea to make two lists.我认为列出两个列表是个好主意。 One words_product and the second one words_conjuction.一个words_product和第二个words_conjuction. First list only contains items like 'Banana', 'Milk' and here you will add all the products you will make buttons for.第一个列表仅包含“香蕉”、“牛奶”等项目,您将在此处添加您将为其制作按钮的所有产品。 The second list is words_conjuction which contains only products separators like 'and', 'or' and whatever you are going to add in the future.第二个列表是words_conjuction ,它只包含产品分隔符,如“和”、“或”以及您将来要添加的任何内容。 With separating items on two mentioned groups (lists), it's easier to write code which will validate your input and to maintain the code in the future when you will add more words.通过将两个提到的组(列表)中的项目分开,编写代码来验证您的输入并在将来添加更多单词时维护代码会更容易。 And the main reason is: these two groups will definitely have different "validation rules".而主要原因是:这两组肯定会有不同的“验证规则”。

For example:例如:

if all([item not in phrase]):
            phrase.append(item)

Line phrase.append(item) will be only executed if all elements in list in all([item not in phrase]) will be True.只有当 list in all([item not in phrase])中的所有元素都为 True 时,才会执行行phrase.append(item) In this case: if currently there is no 'item' in list phrase, add 'item' to the phrase list.在这种情况下:如果列表短语中当前没有“项目”,则将“项目”添加到短语列表中。

If you want to add your own validation rule you can just add something to the list:如果您想添加自己的验证规则,您可以在列表中添加一些内容:

if all([item not in phrase, len(phrase) > 2]):
                phrase.append(item)

It will add the item to the phrase list only when item is not currently in the phrase list and if phrase list length is greater then 2.只有当项目当前不在短语列表中并且短语列表长度大于 2 时,它才会将项目添加到短语列表中。

And also, as suggested before, there is possibility of making buttons normal/disabled (clickable/not clickable) but to be honest I'm not sure which way is better in this case.而且,如前所述,有可能使按钮正常/禁用(可点击/不可点击),但老实说,我不确定在这种情况下哪种方式更好。 It depends how your program will finally look and what product/separators you are going to add.这取决于您的程序最终的外观以及您要添加的产品/分隔符。 But here is the way you can change the button state:但您可以通过以下方式更改按钮 state:

button_name.config(state='normal')
button_name.config(state='disabled')

Example of using button state:使用按钮 state 的示例:

If you want to prevent user from pressing "add" button more then one time in a row, then you can just disable the "add" button after it's pressed and enable when user will press one of the product buttons.如果您想阻止用户连续多次按下“添加”按钮,那么您可以在按下“添加”按钮后禁用它,并在用户按下其中一个产品按钮时启用。

Simplified program example to show you how it works:简化的程序示例向您展示它是如何工作的:

from tkinter import *

phrase = []
outputstring = 'Press some buttons'
products = ['Banana', 'Milk']


def press(item):
    if item in products:
        button_1.config(state='disabled')
        button_2.config(state='disabled')
        button_and.config(state='normal')
    else:
        button_1.config(state='normal')
        button_2.config(state='normal')
        button_and.config(state='disabled')

    phrase.append(item)

    phrase_string = ''
    for ele in phrase:
        phrase_string += ele

    return output.config(text=phrase)


app = Tk()
app.title("Slly Calculator")
app.geometry('350x200')
app.configure(bg='pink')

# widgets
output = Label(app, text=outputstring, width='50')
button_1 = Button(app, text=' Banana ', fg='yellow', bg='purple', command=lambda: press('Banana'), height=2, width=10)
button_2 = Button(app, text=' Milk ', fg='brown', bg='pink', command=lambda: press('Milk'), height=2, width=10)
button_and = Button(app, text='AND', fg='black', bg='white', command=lambda: press("and"), height=2, width=10)

# grid
output.grid(row=0, column=0, columnspan='3', pady='10')
button_1.grid(row=2, column=0, sticky="NSEW")
button_2.grid(row=2, column=1, sticky="NSEW")
button_and.grid(row=4, column=0, sticky="NSEW")


app.mainloop()

If you want to disactivate a button when program starts (for example "and" to prevent user from writing something like "and Banana and Milk")如果您想在程序启动时禁用按钮(例如“and”以防止用户编写“and Banana and Milk”之类的内容)

Change:改变:

button_and = Button(app, text='AND', fg='black', bg='white', command=lambda: press("and"), height=2, width=10) 

to:至:

button_and = Button(app, text='AND', fg='black', bg='white', command=lambda: press("and"), height=2, width=10, state='disabled')

I hope you understand it better now:)我希望你现在能更好地理解它:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM