ScrollList class command argument

I’m pretty sure this is due to my relative Python inexperience and there’s a simple correction.

I have a scrollist I use to select items in a folder. It works fine, but now I need to have a similar list in few other places. So I decided to make it a class. I was able to do it pretty easily and it works fine.

class myGUIList(DirectObject.DirectObject):
	def __init__(self, listType, parent, pos, size):
		self.frame = DirectScrolledList(parent=parent,
			pos = (-.8, 0, 0),
			itemFrame_pos = (0, 0, 0),
			frameSize = (-.5, .62, .825, -.8),
			itemFrame_frameSize = (-.48, .6, .75, -.75),
			frameColor = (0,0,1,0.5),
			itemFrame_frameColor = (0,0,0,1),
			numItemsVisible = 21,
			forceHeight = .07,
			decButton_text = "Up",
			decButton_text_scale = 0.035,
			decButton_frameSize = (-.075,.075,-.04,.04),
			decButton_text_font=base.GAME_FONT,
			decButton_pos = (.1, 0, .8),
			decButton_borderWidth = (0.03, 0.03),
			incButton_text = "Dn",
			incButton_text_scale = 0.035,
			incButton_frameSize = (-.075,.075,-.04,.04),
			incButton_text_font = base.GAME_FONT,
			incButton_pos = (.25, 0, .8),
			incButton_borderWidth = (0.03, 0.03),
			)
		self.lstPgUp = myGUI("button_small","PgUp", self.PgScroll, ["-25"], (.4,0,.8), self.frame)
		self.lstPgDn = myGUI("button_small","PgDn", self.PgScroll, ["25"], (.55,0,.8), self.frame)

		# get list of files and load into scroll list
		if listType == "HERO":
			flist = os.listdir(base.GAME_STORY_CHAR_DATA)
		else:
			flist = os.listdir(base.GAME_STORY_OBJ_DATA)
		self.fdict = {}
		for file in flist:
			name = file.rsplit(".")[0]				# drop file extension
			button = DirectButton(text = name, text_align =TextNode.ALeft, text_font=base.GAME_FONT,
				text_scale = 0.05, text_pos=(-.45,.7, 0), relief = None,
				text0_fg=(0,0,1,1), text1_fg=(1,0,0,1), text2_fg=(1,1,0,1), text3_fg=(0,1,1,1),
				text0_bg=(0,0,0,1),text2_bg=(0,0,0,1), 
				command=self.itemSelected, extraArgs=[name])
			self.frame.addItem(button)
			self.fdict[name] = button			# dictionary of names and buttons 

	def itemSelected(self, name):
		self.parent.itemSelect(name)

	def PgScroll(self, scroll):
		scroll = int(scroll)
		self.frame.scrollBy(scroll)

The only stumbling block now is how do I get the command argument to call a method in the calling code?

The class is called like this:

class myCharEditor(DirectObject.DirectObject):
	def __init__(self):
		base.scrChar = myGUI("screen", "game_characters")

		# Create scroll list control frame and controls
		base.lstChar = myGUIList("HERO", base.scrChar, (.8, 0, 0), (-.5, .62, .825, -.8))

“base.scrChar” is a 2d frame that’s on the screen when I call this list.

But I get this error when clicking something the list.

AttributeError: myGUIList instance has no attribute 'parent'

The calling class myCharEditor has a method called “itemSelect”. That is what I am trying to call from the class myGUIList.
Is this maybe not the right approach?

Your not setting self.parent at any point.

put a self.parent=parent in your init(…) method

Thanks, that got me a step further, but I think I’ve figured out my real problem.

  1. In my main program, I’m creating an object from a class called “myCharEditor”. (base.charEditor = myCharEditor)

  2. In the init for myCharEditor, I create a frame (base.scrChar) and I call my custom ScrollList class:

base.scrChar = myGUI("screen", "game_characters") 

base.lstChar = myGUIList("HERO", base.scrChar, (.8, 0, 0), (-.5, .62, .825, -.8))
  1. As a test, I hard-coded base.scrChar.itemSelect in the class (that is the method I want to call)
	def itemSelected(self, name):
		base.charEditor.itemSelect(name)

It works perfectly! When I try passing “base.charEditor” as a parameter to creating the list and modify itemSelected to use this passed parameter,

base.lstChar = myGUIList("HERO", base.scrCharEditor, (.8, 0, 0), (-.5, .62, .825, -.8))

I get “AttributeError: myGame instance has no attribute ‘charEditor’”

I think it’s because since I am still in the init of myCharEditor, the object hasn’t been created yet and I can’t refer to it in my call to create the list.

SO I just need some design suggestions - I can move my itemSelect ehtod on charEditor to somewhere else (main app?) or is there a better way to have something you click in a scroll list pass back what you clicked?

I guess I could have the init do everything except create the list and then call a new method on the charEditor objects to setup the list. (Not elegant, but I think it would work)