1

I get this error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Hunter\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "c:\Users\Hunter\Documents\Programming\Python Scripts\Scripts\spoolClient\menuScript.py", line 46, in <lambda>
    updateJsonButton = Button(preferences, text="Save Preferences", command=lambda: updateJson())
  File "c:\Users\Hunter\Documents\Programming\Python Scripts\Scripts\spoolClient\menuScript.py", line 17, in updateJson
    for i, j in zip(entryNames, entry):
  File "C:\Users\Hunter\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1643, in cget
    return self.tk.call(self._w, 'cget', '-' + key)
TypeError: can only concatenate str (not "int") to str

When trying to run my script:

from tkinter import *
from tkinter.ttk import *
from tkinter import messagebox
from tkinter import filedialog
import qrMaker
import qrReader
import json

settings = {}
#define vars
preferencesSkippedRows = [1, 3, 5, 7, 9, 11]


def openPreferences():
    def updateJson():
        print("here")
        for i, j in zip(entryNames, entry):
            print("loopdie")
            value = str(j.get())
            settings[i]=value
        settingsjson = json.dumps(settings)
        print(settingsjson)
        f = open("preferences.json","w")
        f.write(settingsjson)
        f.close()
    preferences = Tk()

    preferences.title("Preferences")
    preferences.iconbitmap(qrMaker.getCurrentPath()+'icon.ico')
    preferences.geometry('400x600')

    topText = Label(preferences, width=30, text="Filament Spool Client Preferences")

    cameraText = Label(preferences, width=30, text="Select Camera Instance:")
    cameraEntry = Combobox(preferences, width=30, values=qrReader.getCameras())

    qrWidthText = Label(preferences, width=30, text="QR Output Width (in.)")
    qrWidthEntry = Entry(preferences, width=30)

    qrHeightText = Label(preferences, width=30, text="QR Output Height (in.)")
    qrHeightEntry = Entry(preferences, width=30)

    text = [cameraText, qrWidthText, qrHeightText]
    entry = [cameraEntry, qrWidthEntry, qrHeightEntry]
    entryNames = ['cameraEntry', 'qrWidthEntry', 'qrHeightEntry']
    updateJsonButton = Button(preferences, text="Save Preferences", command=lambda: updateJson())

    for i in preferencesSkippedRows:
        preferences.grid_rowconfigure(i, minsize=10)

    topText.grid(column = 0, row = 0)
    row=2
    for text, entry in zip(text, entry):
        text.grid(column = 0, row = row)
        entry.grid(column = 1, row = row)
        row+=2
    updateJsonButton.grid(column=1, row=row+2)

    preferences.mainloop()

openPreferences() #I call script.openPreferences() in my main program but I left this here for debugging purposes

I can see from the error message that the error occurs somewhere in the line that my zip function occurs, but I have no idea what causes this. Oddly enough, this error goes away if instead of setting updateJson equal to the command value of my Tkinter button state, I set updateJson, which calls the function right as the button object is initialized. I also know what the error is saying, I just don't know where an integer is coming from, and how I can fix this issue. Any help would be appreciated.

Update: I've just found that the actual zipping of the two lists is not the problem, but when I introduce the for loop, the same error occurs.

  • 1
    You used the `entry` name for two things in the same scope: `for text, entry in zip(text, entry)`. Don't do that. Now `entry` is the wrong thing. – user2357112 May 13 '20 at 22:45
  • Never mind, just thought about it. After `for text, entry in zip(text, entry)` is called, entry gets redefined in the for loop – 1Ghasthunter1 May 13 '20 at 22:54

1 Answers1

0

Answering to close out this thread, answer from "user2357112 supports Monica". The issue in this script is that for text, entry in zip(text, entry) literally uses "entry" in the for loop, and is executed after the button instance is created, meaning that if updateJson is called during the button object initialization, then there will be no error thrown as entry is still defined as a list. However, after for text, entry in zip(text, entry) executes at startup, entry is now defined as the last object in the list entry, no longer the list entry itself. When the user presses the button and updateJson is called, an error is thrown as entry is not a list anymore(I'm not 100% sure on the error part).