I am having problems with command on dialog

Could comeone give me a small example of using commands in
DirectDialog? I am not understanding the example in the manual- for example where do I place the function the command calls?

Actaully let me say what I am doing:

I have a collission with a character that brings up a direct.dialog screen- when I press a button I want to update the dialogue text and when I click the close button to close the dialog screen.

I can get the screen up and make the buttons, but I dont see any response when I press the buttons.



You need to make a function which you attach to the dialog with the command= parameter in th constructor. This function will be called with an argument, depending on how you set buttonValueList.

I keep trying and I am getting no where!

My probolem is simply a problem of pointing to the correct variable:

(Unless My idea is wrong)

Here is what happens on a collision with a charcter a directDialog is created.

And when you click the button it runs my function,

but I cannot reference the Dialog anymore!

I get local variable not defined or if I set it to global variable then it says global variable not defined. I have tried dozens of different ways and read several different websites on global and local variables and I am not getting why this doesn’t work.

SO I keep going and now I dont get any errors but the text does not change:

When my function runs I just want to update the text on my dialog or close it. This is so simple a task but it’s making me feel very frustrated.

chattxt="What do you want sonny?"

def grannychat(arg1,arg2):
        global chattxt
        chattxt="Goaway boy!"               
        thischat=DirectDialog(text=(chattxt), buttonTextList=["What?"])

def mygrannychat():
    global thischat
    thischat=DirectDialog(text=(chattxt), buttonTextList=["What?"], command = grannychat(0,0))
    portrait=OnscreenImage("models/karmask01.jpg",pos=(-.8,0,.6), scale=0.33)

here is where it is called from collision:

        for i in self.mana:
            lenVector = self.ralph.getPos() - self.mana[ii].getPos()
            if lenVector.length()<0.6:
                if self.mana[ii].getTag('type')=="watergem":
                if self.mana[ii].getTag('type')=="oldkitsune":
                del self.mana[ii] 
                self.textObject7.setText(str(self.firegems + self.windgems + self.deathgems+ self.watergems + self.earthgems))        
        return Task.cont


JB SKaggs

You need to store the dialog in a global variable (which can be None first) or the dialog will go out of scope and get garbage collected by Python.

I got this to work by finding a copy of Airblade and looking at the StartMenu.py file.

All I had to do to fix my dialog was to change

def grannychat(arg1,arg2)


def grannychat(self)

And then update my command=self.grannychat(self)

I kind of understand why this works, but not really. In my last langauge I could just set a varible to Public and access it from anywhere and I am struggling with how the variables work in python.

I have gone and bought a book on python and I am going to try and work thru all the exercises.

But if anyone can explain to me what is going on with the (self) argument I would be very grateful.

JB Skaggs

Actually putting this in the constructor:


is wrong - it will first execute self.grannychat(self), then pass the result of that function (None, most likely) to the command= argument. So when you click that button, nothing will happen.
If you want to pass arguments, you need to use extraArgs.


In python, any time you see parenthesis, i.e. “something()” that means “execute something and replace something() with the result”. The command= argument for directdialog needs to take a function, which it will call when it is clicked on. You can pass around functions just like any other variable in python, by leaving the parenthesis off. This is why you need to use extra args, to tell directdialog what to pass into the function when it runs it.

function <- something that can be run
function() < - run it and return

Okay I can now make it work with one button- I am understanding a little bit about this now and I can make my dialog scroll down through several layers of text based on one button.

So I must now change the behavior of my functions based on which button gets pushed. Button numbers can vary from one to five.

So how does the buttonValueList work and how do I pass that button over to the command line? This is not in the example provided in the manual:

here is the example from the manual:

import direct.directbase.DirectStart
from direct.gui.OnscreenText import OnscreenText 
from direct.gui.DirectGui import *
from direct.task import Task
from direct.actor import Actor
from direct.interval.IntervalGlobal import *
from pandac.PandaModules import *

#add some text
bk_text = "DirectDialog- YesNoDialog Demo"
textObject = OnscreenText(text = bk_text, pos = (0.85,0.85), 
scale = 0.07,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=1)

#add some text
output = ""
textObject = OnscreenText(text = output, pos = (0.95,-0.95),
 scale = 0.07,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=1)

#callback function to set  text 
def itemSel(arg):
		output = "Button Selected is: Yes"
		output = "Button Selected is: No"

#create a frame
dialog = YesNoDialog(dialogName="YesNoCancelDialog", text="Please choose:", command=itemSel)

#run the tutorial

I do not see any of the directDialog arguments on here… such as buttonValueList, buttonTextList etc. . .

I am sorry for being so dense but shouldn’t an example of directDialog use the arguments listed rather than some other method I can’t figure out? I am assuming that this example is pulling in predefined functions from another file somewhere.

This appears to an if or that function, that doesn’t apply to more than two buttons.

So how do I setup my buttonValueList and call my command based on that list?

Thank you,

JB Skaggs

Well, just add it to the constructor, like you would do with any Python function.

dialog = YesNoDialog(dialogName="YesNoCancelDialog", text="Please choose:", command=itemSel, buttonValueList=[1, 2])

Thanks for putting up with me- its working now.