-1

I am a total beginner here. I would like to know the coordinates of x1 while it is moving, so it will be keep updating.

Here is my code.

from tkinter import *
import tkinter as tk
import time 
import random

class Example(tk.Frame):
    def __init__(self,parent):
        tk.Frame.__init__(self)`

        #create a canvas
        self.canvas = tk.Canvas(width=600, height=250)
        self.canvas.pack()
        self.road()
        self.crossing()

    def road(self):
        Line1 = self.canvas.create_line(50, 50, 450, 50)
        Line2 = self.canvas.create_line(50, 100, 450, 100)

    def crossing(self):
        CLine1 = self.canvas.create_line(350, 50, 350, 100)
        CLine2 = self.canvas.create_line(375, 50, 375, 100)

class Car:
    def __init__(self,x1,y1,x2,y2,vx,vy,color,Example):
        self.x1 = x1
        self.y1 = y1
        self.x2 = x2
        self.y2 = y2
        self.vx = vx
        self.vy = vy
        self.color=color
        self.Example = Example
    def drawit(self):
        self.Example.canvas.create_rectangle(x1,y1,x2,y2,color)
    def moveit(self,vx,vy):
        self.Example.canvas.move(vx,vy)

if __name__ == "__main__":
    root = tk.Tk()
    my_canvas = Example(root).pack(fill="both", expand=True)
    mycar = Car(60, 60, 125, 90,3,0,"red",Example)
    mycar.drawit()
    mycar.moveit()
    print (mycar.x1)
    root.mainloop()

Here is the error message:

AttributeError: type object 'Example' has no attribute 'canvas'

Process finished with exit code 1

Any help would be much appreciated.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
CPG
  • 5
  • 1
  • 4
  • You haven't declared `self.canvas` in your `Car` class. – Qwerp-Derp Jan 20 '17 at 07:24
  • If I declared `self.canvas` in my `Car` class, wouldn't be there another canvas? I meant they (car and road) should be in the same canvas. – CPG Jan 20 '17 at 08:05
  • The `self.canvas` thing is where the error is (because it says that `Car` doesn't have the attribute `canvas`), but I haven't touched tkinter in a while. – Qwerp-Derp Jan 20 '17 at 08:07
  • `Copy + paste` some code and ask "why not work?" You forget `member` status ! `my_canvas = Example(root).pack(fill="both", expand=True)` than `my_canvas.canvas .....` or copy Example class to in Car class. – dsgdfg Jan 20 '17 at 08:08
  • I don't really know how to start it so I tried to copy and understand it... `class Car(Example)` like this? or how? Thanks for your help – CPG Jan 20 '17 at 08:28
  • I rolled this question back one revision, the OP had edited it to be a completely different question after a couple answers had already been given. – Bryan Oakley Jan 23 '17 at 04:12
  • Thanks @BryanOakley – CPG Jan 23 '17 at 06:09

2 Answers2

1

You have some basic misunderstandings of how classes and objects work. Instead of doing this:

my_canvas = Example(root)
my_canvas.pack(fill="both", expand=True)
mycar = Car(60, 60, 125, 90,3,0,"red",Example)

(note: you also need to call pack on a separate line from where the widget is created and assigned to a variable. See https://stackoverflow.com/a/1101765/7432)

You need to do this:

my_canvas = Example(root).pack(fill="both", expand=True)
mycar = Car(60, 60, 125, 90,3,0,"red", my_canvas)

You need to pass in the instance of Example (eg: my_canvas), not the class (eg: Example). Also, Car needs to use the example like this:

class Car:
    def __init__(self,x1,y1,x2,y2,vx,vy,color,example):
        ...
        self.example=example
    def drawit(self):
        self.example.canvas.create_rectangle(x1,y1,x2,y2,color)
    def moveit(self,vx,vy):
        self.example.canvas.move(vx,vy)
Community
  • 1
  • 1
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Now the error message become like this `AttributeError: 'NoneType' object has no attribute 'canvas'` I need to clarify, do I pass the class Example if I use "example"? – CPG Jan 23 '17 at 03:50
  • @CPG: that's a different problem, and has been answered here: http://stackoverflow.com/a/1101765/7432. I've updated my answer to cover that. – Bryan Oakley Jan 23 '17 at 03:52
  • 1
    @CPG: that's now how stackoverflow works. You have now completely invalidated the answers that people like spent time writing. If you have another question, _ask another question_ (after doing research on this new question first!). Please don't edit your original question to be something completely different than it was. I've rolled back your edit to the original question. – Bryan Oakley Jan 23 '17 at 04:11
0

Your Car doesn't have access to the Example object. I would pass my Example to my Car on init, so that it can access its context. e.g.

class Car:
    def __init__(self, x, y, example):
        ...
        self.example=example
    def do_stuff(self):
        self.example.canvas.draw(whatever)

example = Example(args)
car = Car(3,4,example)
car.do_stuff()

In this example, Car objects have access to the canvas that you create in your Example class, so they can draw themselves, etc.

Him
  • 5,257
  • 3
  • 26
  • 83
  • `class Car: def __init__(self,x1,y1,x2,y2,vx,vy,color,Example): self.x1 = x1 self.y1 = y1 self.x2 = x2 self.y2 = y2 self.vx = vx self.vy = vy self.color=color self.Example = Example def drawit(self): self.Example.canvas.create_rectangle(x1,y1,x2,y2,color) mycar = Car(60, 60, 125, 90,3,0,"red",Example) mycar.drawit()` `Now the error message is AttributeError: type object 'Example' has no attribute 'canvas'` – CPG Jan 23 '17 at 02:51