«Объект int не является итеративным» Кнопка Tkinter - PullRequest
0 голосов
/ 12 марта 2019

В моем коде я определяю серию кнопок, используя цикл for, и когда нажимается зеленая, запускается функция. Моя проблема, я думаю, заключается в том, что когда она запускает функцию, она делает это внутри класса Button и, таким образом, не использует глобальное значение, которое я хочу.

##def of the for loop to make the buttons##
for x in range(len(ProjectList)):
    if ProjectList[x][1] > money:
        buylist[x] = Button(buyf, text = ProjectList[x][1], bg = "red", fg = "white")

    elif ProjectList[x][1] <= money:
        buylist[x] = Button(buyf, text = ProjectList[x][1], command = lambda n=x: buycheck(n,money, moneyps), bg="green", fg="white")

##function called when button pressed##
def buycheck(numbbuy,money, moneyps):
    ##error checking stuff##

    ##buy function##
    buy(numbbuy,money, moneyps)

##function that does the purchase##
def buy(numbbuy,money, moneyps):

    money -= int(ProjectList[numbbuy][1])
    moneyps += int(ProjectList[numbbuy][0])

ProjectList - 11 строк по 2 столбца чисел.

money и moneyps - целые числа, определенные в начале.

Ошибка возникает в функции buy() в строках назначения для money и moneyps. Показанная ошибка:

moneyps += int(ProjectList[numbbuy][0])
TypeError: 'int' object is not iterable

Полный код:

from tkinter import *
from time import *

##############globals##############
global ProjectList
global gamecomplete
global money
global moneyps

##############values for init##############
names = [
"Reusable Rockets" ,
"Space elevator"   ,
"Orbital rings"    ,
"Asteroid mining"  ,
"1Space clean up"  ,
"1Mars colony"     ,
"Planet mining"    ,
"1Dyson Swarm"     ,
"1Dyson sphere"    ,
"Sun mining"       ,
"Space colony"     ,
"Colony Ship"      ,
]

ProjectList = [
#   name            PS      cost
[100,   3000],  #0
[200,   6000],  #1
[300,   9000],  #2
[400,   12000], #3
[500,   13000], #4
[600,   15000], #5
[700,   16000], #6
[800,   17000], #7
[900,   18000], #8
[1000,  19000], #9
[1100,  20000], #10
[0,     21000]  #11
]

gamecomplete = False
money = 10000
moneyps = 200
boughtitems = []

##############functions##############
def buy(numbbuy,money, moneyps):

    money -= int(ProjectList[numbbuy][1])
    moneyps += int(ProjectList[numbbuy][0])
    names.append(ProjectList[numbbuy])
    print("money", money)
    print("moneyps", moneyps)

##############Checks to see what it needs to do befre it can be bought##############
def buycheck(numbbuy,money, moneyps):
    ##############it can only be bought once##############
    if names[numbbuy][0] == "1":
        buy(numbbuy,money, moneyps)
        names.pop(numbbuy)
    ##############its the last thing to buy to win the game##############
    elif numbbuy == 11:
        gamecomplete = True
    ##############normal buys##############
    else:
        buy(numbbuy,money, moneyps)

##############UI creation##############
def ui(money, moneyps):
    ##############init##############
    win = Tk()
    buyf = Frame()

    ##############headder##############
    headder = Label(win,text = "Money = $"+str(money)+"\t$/s = $"+str(moneyps))

    ##############title##############
    projectname = Label(buyf,text = "Project names")
    projectPS = Label(buyf, text = "$/s added")
    buybutton = Label(buyf, text = "buy")

    ##############title gridded##############
    projectname.grid(row = 0, padx = 2)
    projectPS.grid(row = 0, column = 1, padx = 2)
    buybutton.grid(row = 0, column = 2, padx = 2)

    buildproj = list()
    moneyps = list()
    buylist = list()

    ##############name of build proj // money PS // buy button##############

    #defines empty lists
    buildproj = [None] * len(ProjectList)
    moneyps = [None] * len(ProjectList)
    buylist = [None] * len(ProjectList)

    #for loop to make all the buttons
    for x in range(len(ProjectList)):

        #clean up input
        if names[x][0] == "1":
            temp == names[x][1::]

        else:
            temp = names[x]

        #define content
        buildproj[x] = Label(buyf, text = temp)
        moneyps[x] = Label(buyf, text = ProjectList[x][0])

        if ProjectList[x][1] > money:
            buylist[x] = Button(buyf, text = ProjectList[x][1], bg = "red", fg = "white")

        elif ProjectList[x][1] <= money:
            buylist[x] = Button(buyf, text = ProjectList[x][1], command = lambda n=x: buycheck(n,money, moneyps), bg="green", fg="white")

        #grid it
        buildproj[x].grid(row = x+1, sticky = "e")
        moneyps[x].grid(row = x+1, column =1)
        buylist[x].grid(row = x+1, column = 2, sticky = "nesw")

    ##############quit button##############
    quit = Button(win, text = "Quit", command=win.quit, bg = "red", fg = "white")

    ##############research update##############
    status = Label(win, text="current research % complete", bd = 1, relief = SUNKEN, anchor = W)

    ##############packing##############
    headder.pack()
    buyf.pack()
    quit.pack(fill = "x")
    status.pack(side=BOTTOM, fill = "x", )

    win.mainloop()

##############Body##############
ui(money, moneyps)

Ответы [ 2 ]

1 голос
/ 12 марта 2019

Ошибка говорит вам, что когда вы пытаетесь выполнить moneyps += int(ProjectList[numbbuy][0]), вы индексируете что-то (целое число в данном случае), которое не повторяется (не может быть проиндексировано). Основываясь на ваших именах переменных, я бы предположил, что ProjectList - это список , и из-за ошибки я думаю, что это выглядит примерно так:

ProjectList = [1, 3, 7, 11, 9] #some integers

Допустим, ваш numbbuy равен 2, а затем

moneyps += int(ProjectList[numbbuy][0])

соответствует

moneyps += int(7[0])

Поскольку ProjectList проиндексирован на 2 -> 7. Затем вы просите компьютер разбить 7 на итерируемый список / строку и затем принять первое значение (0-й индекс). Это физически не имеет смысла делать. Так как это первая вещь, которую вы собираетесь купить, я бы порекомендовал попробовать:

moneyps += int(ProjectList[numbbuy]) # Just remove [0]

Это просто уменьшит до:

moneyps += int(7)

В нашем примере выше, я думаю, вы пытаетесь это сделать. Однако для более правильного ответа вам нужно будет предоставить гораздо больше деталей для создания MCVE, с которым мы можем помочь (см. Ссылку в комментарии @Пруна, оставленная для вас)

UPDATE

С вашим полным кодом я обнаружил, что

moneyps = [<tkinter.Label object .1294806022968.1294809795776>, <tkinter.Label object .1294806022968.1294809795944>, <tkinter.Label object .1294806022968.1294809796168>, <tkinter.Label object .1294806022968.1294809796392>, <tkinter.Label object .1294806022968.1294809804872>, <tkinter.Label object .1294806022968.1294809805040>, <tkinter.Label object .1294806022968.1294809805208>, <tkinter.Label object .1294806022968.1294809805376>, <tkinter.Label object .1294806022968.1294809805544>, <tkinter.Label object .1294806022968.1294809805712>, <tkinter.Label object .1294806022968.1294809805880>, <tkinter.Label object .1294806022968.1294809806048>]

И поэтому ваша строка moneyps += int(ProjectList[numbbuy][0]) не имеет никакого смысла, потому что вы пытаетесь добавить целое число со списком.

0 голосов
/ 12 марта 2019

Думаю, проблема в том, что вы не понимаете, как глобальные переменные работают в Python и что делает оператор global (то есть он не «определяет» переменную). Эти операторы global в самом начале ничего не делают - за исключением, возможно, в качестве документации - потому что они находятся на уровне модуля и любые переменные определены в любом случае будут глобальными.

global операторы нужны внутри любой функции, которая желает изменить значение переменной (нет необходимости просто ссылаться на текущее значение единицы).

Учитывая эту информацию, избежать TypeError можно, изменив код, как я указал ниже с комментариями #--->. Тем не менее, я не могу сказать, действительно ли ваша программа действительно работает сейчас, потому что я не совсем понимаю, что вы пытаетесь заставить ее делать. Наличие параметров функций и глобальных переменных с одним и тем же именем, но разными типами, в лучшем случае очень запутанно (на что указывает @ acw1668 в комментарии к вашему вопросу, а также в ответе @ Reedinationer).

from tkinter import *
from time import *

##############globals##############
#global ProjectList   # Does nothing.
#global gamecomplete  # Does nothing.
#global money         # Does nothing.
#global moneyps       # Does nothing.

##############values for init##############
names = [
"Reusable Rockets" ,
"Space elevator"   ,
"Orbital rings"    ,
"Asteroid mining"  ,
"1Space clean up"  ,
"1Mars colony"     ,
"Planet mining"    ,
"1Dyson Swarm"     ,
"1Dyson sphere"    ,
"Sun mining"       ,
"Space colony"     ,
"Colony Ship"      ,
]

ProjectList = [
#   name            PS      cost
[100,   3000],  #0
[200,   6000],  #1
[300,   9000],  #2
[400,   12000], #3
[500,   13000], #4
[600,   15000], #5
[700,   16000], #6
[800,   17000], #7
[900,   18000], #8
[1000,  19000], #9
[1100,  20000], #10
[0,     21000]  #11
]

gamecomplete = False
money = 10000
moneyps = 200
boughtitems = []

##############functions##############
def buy(numbbuy):  #---> Removed money, moneyps parameters
    global money, moneyps  #---> Added
    money -= int(ProjectList[numbbuy][1])
    moneyps += int(ProjectList[numbbuy][0])
    names.append(ProjectList[numbbuy])
    print("money", money)
    print("moneyps", moneyps)

##############Checks to see what it needs to do befre it can be bought##############
def buycheck(numbbuy):   #---> Removed money, moneyps parameters
    global money, moneyps  #---> Added
    ##############it can only be bought once##############
    if names[numbbuy][0] == "1":
        buy(numbbuy,money, moneyps)
        names.pop(numbbuy)
    ##############its the last thing to buy to win the game##############
    elif numbbuy == 11:
        gamecomplete = True
    ##############normal buys##############
    else:
        buy(numbbuy)  #---> Removed money, moneyps parameters

##############UI creation##############
def ui(money, moneyps):
    ##############init##############
    win = Tk()
    buyf = Frame()

    ##############headder##############
    headder = Label(win,text = "Money = $"+str(money)+"\t$/s = $"+str(moneyps))

    ##############title##############
    projectname = Label(buyf,text = "Project names")
    projectPS = Label(buyf, text = "$/s added")
    buybutton = Label(buyf, text = "buy")

    ##############title gridded##############
    projectname.grid(row = 0, padx = 2)
    projectPS.grid(row = 0, column = 1, padx = 2)
    buybutton.grid(row = 0, column = 2, padx = 2)

    buildproj = list()
    moneyps = list()
    buylist = list()

    ##############name of build proj // money PS // buy button##############

    #defines empty lists
    buildproj = [None] * len(ProjectList)
    moneyps = [None] * len(ProjectList)
    buylist = [None] * len(ProjectList)

    #for loop to make all the buttons
    for x in range(len(ProjectList)):

        #clean up input
        if names[x][0] == "1":
            temp == names[x][1::]

        else:
            temp = names[x]

        #define content
        buildproj[x] = Label(buyf, text = temp)
        moneyps[x] = Label(buyf, text = ProjectList[x][0])

        if ProjectList[x][1] > money:
            buylist[x] = Button(buyf, text = ProjectList[x][1], bg = "red", fg = "white")

        elif ProjectList[x][1] <= money:
            buylist[x] = Button(buyf, text = ProjectList[x][1],
#               command = lambda n=x: buycheck(n,money, moneyps), bg="green", fg="white")
                command = lambda n=x: buycheck(n), bg="green", fg="white")  #---> Changed
        #grid it
        buildproj[x].grid(row = x+1, sticky = "e")
        moneyps[x].grid(row = x+1, column =1)
        buylist[x].grid(row = x+1, column = 2, sticky = "nesw")

    ##############quit button##############
    quit = Button(win, text = "Quit", command=win.quit, bg = "red", fg = "white")

    ##############research update##############
    status = Label(win, text="current research % complete", bd = 1, relief = SUNKEN, anchor = W)

    ##############packing##############
    headder.pack()
    buyf.pack()
    quit.pack(fill = "x")
    status.pack(side=BOTTOM, fill = "x", )

    win.mainloop()

##############Body##############
ui(money, moneyps)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...