Forum Archive

Can I use CourseView without defining it or importing it?

Python567

I have a problem that I don‘t understand:
I have a class with follow in it:

self.cv = CourseView(game, frame=(buttonWidth, 0, (screenWidth-2*buttonWidth), screenHeight))

And a other class with CourseView. Now the Problem is, that there come a error: „Course View is not defined“
Why?

mikael

@Python567, many ways to have a mistake in how you reference classes or instances. Maybe share a bit of relevant code?

Python567

@mikael said:

many ways to have a mistake in how you reference classes or instances. Maybe share a bit of relevant code?

@mikael here is the complete class where the error come:

class GameView (ui.View):
    def __init__(self, game):
        self.bg_color = 'white'
        self.game = game
        self.multitouch_enabled = True
        self.cv = None

        ''' 
        # Create the racing course, buttons on the left and right, not on top or buttom
        self.cv = CourseView(game, frame=(buttonWidth, 0, (screenWidth-2*buttonWidth), screenHeight))
        self.add_subview(self.cv)
        self.cv.touch_enabled = False

        '''
        self.resetCourseView(game)

        # Create CarControllers and add their buttons views to the screen
        self.carController = []
        id = 0
        while (id < 4):
            self.carController.append(CarController(self.cv.getCar(id)))
            self.add_subview(self.carController[id])        
            id += 1

        # Create the menu buttons
        self.start_button = ui.ButtonItem()
        self.start_button.title = '  Start  '
        self.start_button.action = self.start_action
        self.pause_button = ui.ButtonItem()
        self.pause_button.title = '  Pause  '
        self.pause_button.action = self.pause_action
        self.player_button = ui.ButtonItem()
        self.player_button.title = '  Player (1)  '
        self.player_button.action = self.player_action
        self.speed_button = ui.ButtonItem()

        self.stop_button = ui.ButtonItem()
        self.stop_button.title = ' Auch ein Startknopf '
        self.stop_button.action = self.start_action

        self.speed_button.title = '  Speed (' + str(initialSpeed) + ')  '
        self.speed_button.action = self.speed_action
        self.left_button_items = [self.start_button, self.pause_button, self.player_button, self.speed_button, self.stop_button]


        self.score_button = ui.ButtonItem()
        self.score_button.title = '  Collisions (0,0,0,0)  '
        self.score_button.action = self.speed_action # TODO
        self.right_button_items = [self.score_button]

    def resetCourseView(self, game):
        # delete old courseView if existing
        if self.cv != None:
            # print ("Old CourseView exists")
            self.remove_subview(self.cv)
        # Create the racing course, buttons on the left and right, not on top or buttom
        self.cv = CourseView(game, frame=(buttonWidth, 0, (screenWidth-2*buttonWidth), screenHeight))
        self.add_subview(self.cv)
        self.cv.touch_enabled = False
mikael

@Python567, where do you define or import CourseView?

cvp

@mikael said:

where do you define or import CourseView?

I hadn't dared to ask 🤔

Python567

@mikael I define CourseView in a extra class. But I think the problem is an other one. On this Code I print a text when I press the button:

from scene import *
import ui
import sound
A = Action

class ButtonNode (SpriteNode):
    def __init__(self, title, *args, **kwargs):
        SpriteNode.__init__(self, 'pzl:Button1', *args, **kwargs)
        button_font = ('Avenir Next', 20)
        self.title_label = LabelNode(title, font=button_font, color='black', position=(0, 1), parent=self)
        self.title = title

class MenuScene (Scene):
  def __init__(self, title, subtitle, button_titles, *args, **kwargs):
    Scene.__init__(self, *args, **kwargs)
    self.title = 'title'#title
    self.subtitle = 'subtitle'#subtitle
    self.button_titles = ['Play']#button_titles

  def setup(self):
    button_font = ('Avenir Next', 20)
    title_font = ('Avenir Next', 36)
    num_buttons = len(self.button_titles)
    self.bg = SpriteNode(color='black', parent=self)
    bg_shape = ui.Path.rounded_rect(0, 0, 240, num_buttons * 64 + 140, 8)
    bg_shape.line_width = 4
    shadow = ((0, 0, 0, 0.35), 0, 0, 24)
    self.menu_bg = ShapeNode(bg_shape, (1,1,1,0.9), '#15a4ff', shadow=shadow, parent=self)
    self.title_label = LabelNode(self.title, font=title_font, color='black', position=(0, self.menu_bg.size.h/2 - 40), parent=self.menu_bg)
    self.title_label.anchor_point = (0.5, 1)
    self.subtitle_label = LabelNode(self.subtitle, font=button_font, position=(0, self.menu_bg.size.h/2 - 100), color='black', parent=self.menu_bg)
    self.subtitle_label.anchor_point = (0.5, 1)
    self.buttons = []
    for i, title in enumerate(reversed(self.button_titles)):
        btn = ButtonNode(title, parent=self.menu_bg)
        btn.position = 0, i * 64 - (num_buttons-1) * 32 - 50
        self.buttons.append(btn)
    self.did_change_size()
    self.menu_bg.scale = 0
    self.bg.alpha = 0
    self.bg.run_action(A.fade_to(0.4))
    self.menu_bg.run_action(A.scale_to(1, 0.3, TIMING_EASE_OUT_2))
    self.background_color = 'white'

  def did_change_size(self):
    self.bg.size = self.size + (2, 2)
    self.bg.position = self.size/2
    self.menu_bg.position = self.size/2

  def touch_began(self, touch):
    touch_loc = self.menu_bg.point_from_scene(touch.location)
    for btn in self.buttons:
        if touch_loc in btn.frame:
            sound.play_effect('8ve:8ve-beep-hightone')
            btn.texture = Texture('pzl:Button2')
            self.button_tapped(btn)

  def touch_ended(self, touch):
    for btn in self.buttons:
        btn.texture = Texture('pzl:Button1')
        if self.presenting_scene and touch_loc in btn.frame:
            new_title = self.presenting_scene.menu_button_selected(btn.title)
            if new_title:
                btn.title = new_title
                btn.title_label.text = new_title

  def menu(self):
    pass


  def button_tapped(self, sender):
    print('button tapped:', sender.title)

if __name__ == '__main__':
  run(MenuScene('LeiRacers', 'Subtitle', ['Play']))

At „def button_tapped“ I copy all of the other code in, which I would start when I press the button. Is that right, or is here the mistake?

mikael

@Python567, if I understand your question correctly, I think you might have missed the possibility of importing another file, where you have defined e.g. another class, and then you can just use it in your button action function. No need to ”copy all code there”, as the inported code is available in the global scope.

ccc

To format you code in this forum, please see https://docs.github.com/en/free-pro-team@latest/github/writing-on-github/creating-and-highlighting-code-blocks

Akashbro120

Buy the best fitness band in india under 2000 to keep accountability of your fitness routine. Get the best band now! https://www.fitnessadviser.in/best-fitness-band-under-2000/

Python567

@mikael If I understand you, I must import my file in the menu. And then, how can I insert it in the place I use?

JonB

In order to use something called CourseView, that class name must exist inside the current scope or global scope before you attempt to reference it. How else would the python know what you want?

Typically, if you define your CourseView class in a separate file, say, courseview.py, you need to have an import statement in your main code -- just like you are using import ui, etc.

So, at the start of the code where you would like to reference CourseView, you would write one of the following, depending on how you want your code to look

# import just the stuff you need
from courseview import CourseView 

# or.. import everything from the module, which is sometimes ok if the module was written carefully to avoid conflicting names -- for instance in pythonista people usually import everything from scene -- but except for special cases importing everything makes it really hard to debug or follow code, and usually considered bad form...
from courseview import *

# or, just import only the module name, in which case you access by using courseview.CourseView
import courseview

In any of the examples above, the courseview.py file must exist in the same folder as the file that you are running from the editor play button, and must have a variable/class in the global scope of that module named CourseView. Or, the file must exist in site-packages, or somewhere else on your sys.path. (you can insert paths on sys.path in order to look in a nonstandard location). Eventually you can learn how package folders work, but you don't need them now.

In the Pythonista environment, modules located in site-packages do not get reloaded even when the file is modified, until you quit pythonista -- so if you are editing the module you want to import, it is best to keep it in the same folder as your main script.