-1

I am working on Computer Science Homework and having trouble with it the task is to create a gui with a button that opens a new window and displays information from the Swapi API (found at www.swapi.co) my problem is that it says im missing positional arguements and cannot figure out where they are missing or what i'm doing wrong for the Gui im using the tkinter module and I am also importing a class I made both the program and the class are located below

from tkinter import *
from People import Person

def FormatToString(collection):
        results = ""

        for item in collection:
            response = requests.get(item)
            dataRow = response.json()
            results += " {}, ".format(dataRow['name'])

        return results

def GetHomeWorld(homeworld):
        response2 = requests.get(homeworld)
        Json_data2 = response2.json()
        homeworld = Json_data2['name']
        return homeworld

root = Tk()
root.title('A visual Dictionary of the Star Wars Universe')
root.geometry('{}x{}'.format(460, 350))

# layout all of the main containers
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

# create all of the main containers
top_frame = Frame(root, bg='cyan',padx=100, pady=8)
center = Frame(root, bg='gray', padx=3, pady=3)

top_frame.grid(row=0, sticky="ew")
center.grid(row=1, sticky="nsew")

# create the widgets for the top frame
model_label = Label(top_frame, text='Filter Example')
width_label = Label(top_frame, text='Filter by keyword:')
entry_W = Entry(top_frame, background="pink")
def DataFilter():
    root.title(entry_W.get())
    center.destroy()
button = Button(top_frame, text="Submit", command=DataFilter)

# layout the widgets in the top frame
model_label.grid(row=0, columnspan=3)
width_label.grid(row=1, column=0)
entry_W.grid(row=1, column=1)
button.grid(row=1, column=2)


import json 
import requests

starAPI = "https://swapi.co/api/people/"
response = requests.get(starAPI)
json_data = response.json()



i = 1
Label(center, text= 'StarShips\n=========',  width=20, pady=13, padx=13).grid(row=1, column = 0)
Label(center, text= 'Name\n=====', width=20, pady=13, padx=13).grid(row=1, column = 1)
Label(center, text= 'Birth Year\n==========', width=20, pady=13, padx=13).grid(row=1, column = 2)
Label(center, text= 'Gender\n======', width=10, pady=13, padx=13).grid(row=1, column = 3)
Label(center, text= 'Eye Color\n=========', width=15, pady=13, padx=13).grid(row=1, column = 4)
Label(center, text= 'Homeworld\n========',  width=15, pady=13, padx=13).grid(row=1, column = 5)


for person in (json_data['results']):
    name = str(person['name'])
    birth_year = str(person['birth_year'])
    gender = str(person['gender'])
    eye_color = str(person['eye_color'])
    homeworld = GetHomeWorld(person['homeworld'])
    starships = FormatToString(person['starships'])
    i += 1
    Button(center, text = 'Click Me for StarShips', width = 20, pady = 13, padx = 13, bg = 'black', fg = 'white', command = Person.openwindow(starships)).grid(row=i, column = 0)
    Label(center, text= name, width=20, pady=13, padx=13).grid(row=i, column = 1)
    Label(center, text= birth_year, width=20, pady=13, padx=13).grid(row=i, column = 2)
    Label(center, text= gender, width=10, pady=13, padx=13).grid(row=i, column = 3)
    Label(center, text= eye_color, width=15, pady=13, padx=13).grid(row=i, column = 4)
    Label(center, text= homeworld,  width=15, pady=13, padx=13).grid(row=i, column = 5

root.mainloop()

=====================================================================================================

import json
import requests
from tkinter import *

class Person():
    def __init__(self, name, birth_year, eye_color, gender, homeworld, starships):
        self.name = name
        self.birth_year = birth_year
        self.eye_color = eye_color
        self.gender = gender
        self.starships = self.FormatToString(starships)
        self.homeworld = self.GetHomeWorld(homeworld)

    def FormatToString(self, collection):
        results = ""

        for item in collection:
            response = requests.get(item)
            dataRow = response.json()
            results += " {} |".format(dataRow['name'])

        return results

    def GetHomeWorld(self, homeworld):
        response2 = requests.get(homeworld)
        Json_data2 = response2.json()
        homeworld = Json_data2['name']
        return homeworld

    def openwindow(self, starships):
        window = Tk()
        window.geometry('{}x{}'.format(460, 350))
        window.title('Starships')


        # layout all of the secondary containers
        window.grid_rowconfigure(1, weight=1)
        window.grid_columnconfigure(0, weight=1)

        # create all of the secondary containers
        top_frame2 = Frame(window, bg='cyan',padx=100, pady=8)
        center2 = Frame(window, bg='gray', padx=3, pady=3)

        top_frame2.grid(row=0, sticky="ew")
        center2.grid(row=1, sticky="nsew") 

        Label(center2, text= starships,  width=30, pady=13, padx=13).grid(row=0, column = 0)

        window.mainloop


    def __str__(self):
        return "Name: {}\nBirth year: {}\nGender: {}\nEye Color: {}\nStarships: {}\nHomeworld: {}".format(self.name, self.birth_year, self.gender, self.eye_color, self.starships, self.homeworld)
  • 1
    Please share the error – liorko Dec 03 '19 at 18:33
  • 1
    always put full error message (starting at word "Traceback") in question (not comment) as text (not screenshot). There are other useful information. – furas Dec 03 '19 at 18:34
  • 1
    you should use `Tk()` only to create main window. For other windows use `Toplevel()` – furas Dec 03 '19 at 18:35
  • 1
    Read [Why are multiple instances of Tk discouraged?](https://stackoverflow.com/questions/48045401/why-are-multiple-instances-of-tk-discouraged) – stovfl Dec 03 '19 at 19:02
  • if you use `Person.openstarship(starship)` then it should be static method created with decorator `@staticmethod` and without `self` in `def openstarship(starship)`. And it gives you missing argument. – furas Dec 04 '19 at 00:49
  • `command=` need name of function/method without `()` and without arguments and later it will use `()` to run it. Now you use `Person.openstarship(starship)` so you run this function at start and it open all windows at start, not when you click button. You could use `lambda` to assing function which has to use arguments - and it may need to assign `startship` to new variable to copy value `command=lambda x=starship:Person.openstarship(x)` – furas Dec 04 '19 at 00:52

1 Answers1

0

If you use Person.openstarship(starship) then you run it as static method, not class method, so it doesn't use self and it inform that you have missing value.

You should use decorator @staticmethod and remove self

    @staticmethod
    def openwindow(starships):

OR you would have to create instance of class Person

person_instance = Person(...put values...)
Button(..., command=person_instance.openwindow(starship))

But command= has other mistakes. It needs function name without () and arguments and later it will use()to run this function. To assign method with argument you can uselambda`.

Button(..., command=lambda:person_instance.openwindow(starship))

But using argument in command= which is create in loop need to use new variable to copy access from original variable which will be overwritten in next loop

Button( command=(lambda x=starships:Person.openwindow(x)) )

Other problem: GUI should have only one main window created with Tk(). To create other windows use Toplevel(). In other GUI frameworks can be similar.

All GUI frameworks use main loop (also called event loop) and in all GUI frameworks should be only one main loop - in tkinter it is tkinter.mainloop()


There are other suggestions but they are not mistakes:

  • import * is not prefered, better use import tkinter or very popular import tkinter as tk. And then you have to use tk.Tk(), tk.Button(), etc.

  • methods/functions should have lower_case_names - ie. get_home_world() format_to-string.

All suggestions you can see in PEP 8 -- Style Guide for Python Code


import json
import requests
from tkinter import *

class Person():

    def __init__(self, name, birth_year, eye_color, gender, homeworld, starships):
        self.name = name
        self.birth_year = birth_year
        self.eye_color = eye_color
        self.gender = gender
        self.starships = self.FormatToString(starships)
        self.homeworld = self.GetHomeWorld(homeworld)

    def FormatToString(self, collection):
        results = ""

        for item in collection:
            response = requests.get(item)
            dataRow = response.json()
            results += " {} |".format(dataRow['name'])

        return results

    def GetHomeWorld(self, homeworld):
        response2 = requests.get(homeworld)
        Json_data2 = response2.json()
        homeworld = Json_data2['name']
        return homeworld

    @staticmethod
    def openwindow(starships):
        window = Toplevel()
        #window.geometry('460x350')
        window.title('Starships')


        # layout all of the secondary containers
        window.grid_rowconfigure(1, weight=1)
        window.grid_columnconfigure(0, weight=1)

        # create all of the secondary containers
        top_frame2 = Frame(window, bg='cyan',padx=100, pady=8)
        center2 = Frame(window, bg='gray', padx=3, pady=3)

        top_frame2.grid(row=0, sticky="ew")
        center2.grid(row=1, sticky="nsew") 

        Label(center2, text= starships,  width=30, pady=13, padx=13).grid(row=0, column = 0)

        #window.mainloop()


    def __str__(self):
        return "Name: {}\nBirth year: {}\nGender: {}\nEye Color: {}\nStarships: {}\nHomeworld: {}".format(self.name, self.birth_year, self.gender, self.eye_color, self.starships, self.homeworld)

from tkinter import *

def FormatToString(collection):
        results = ""

        for item in collection:
            response = requests.get(item)
            dataRow = response.json()
            results += " {}, ".format(dataRow['name'])

        return results

def GetHomeWorld(homeworld):
        response2 = requests.get(homeworld)
        Json_data2 = response2.json()
        homeworld = Json_data2['name']
        return homeworld

root = Tk()
root.title('A visual Dictionary of the Star Wars Universe')
#root.geometry('460x350')

# layout all of the main containers
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

# create all of the main containers
top_frame = Frame(root, bg='cyan',padx=100, pady=8)
center = Frame(root, bg='gray', padx=3, pady=3)

top_frame.grid(row=0, sticky="ew")
center.grid(row=1, sticky="nsew")

# create the widgets for the top frame
model_label = Label(top_frame, text='Filter Example')
width_label = Label(top_frame, text='Filter by keyword:')
entry_W = Entry(top_frame, background="pink")
def DataFilter():
    root.title(entry_W.get())
    center.destroy()
button = Button(top_frame, text="Submit", command=DataFilter)

# layout the widgets in the top frame
model_label.grid(row=0, columnspan=3)
width_label.grid(row=1, column=0)
entry_W.grid(row=1, column=1)
button.grid(row=1, column=2)


import json 
import requests

starAPI = "https://swapi.co/api/people/"
response = requests.get(starAPI)
json_data = response.json()

print(json_data)

i = 1
Label(center, text= 'StarShips\n=========',  width=20, pady=13, padx=13).grid(row=1, column = 0)
Label(center, text= 'Name\n=====', width=20, pady=13, padx=13).grid(row=1, column = 1)
Label(center, text= 'Birth Year\n==========', width=20, pady=13, padx=13).grid(row=1, column = 2)
Label(center, text= 'Gender\n======', width=10, pady=13, padx=13).grid(row=1, column = 3)
Label(center, text= 'Eye Color\n=========', width=15, pady=13, padx=13).grid(row=1, column = 4)
Label(center, text= 'Homeworld\n========',  width=15, pady=13, padx=13).grid(row=1, column = 5)


for person in (json_data['results']):
    name = str(person['name'])
    birth_year = str(person['birth_year'])
    gender = str(person['gender'])
    eye_color = str(person['eye_color'])
    homeworld = GetHomeWorld(person['homeworld'])
    starships = FormatToString(person['starships'])
    i += 1
    Button(center, text = 'Click Me for StarShips', width = 20, pady = 13, padx = 13, bg = 'black', fg = 'white', command=lambda x=starships:Person.openwindow(x)).grid(row=i, column = 0)
    Label(center, text= name, width=20, pady=13, padx=13).grid(row=i, column = 1)
    Label(center, text= birth_year, width=20, pady=13, padx=13).grid(row=i, column = 2)
    Label(center, text= gender, width=10, pady=13, padx=13).grid(row=i, column = 3)
    Label(center, text= eye_color, width=15, pady=13, padx=13).grid(row=i, column = 4)
    Label(center, text= homeworld,  width=15, pady=13, padx=13).grid(row=i, column = 5)

root.mainloop()
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
furas
  • 134,197
  • 12
  • 106
  • 148