The problem with setText()

import direct.directbase.DirectStart
from direct.gui.OnscreenText import OnscreenText

TextNode = OnscreenText(text = 'Demo')

# Working
#TextNode.setText('New')

#Does not work
elements = render2d.findAllMatches("**/+TextNode")
for i in elements:
    #id.setText('New')
    pass

base.run()

The problem described in the comments to the code.

import direct.directbase.DirectStart
from direct.gui.OnscreenText import OnscreenText

TextNode = OnscreenText(text = 'Demo')

# Working
#TextNode.setText('New')

# Working
elements = render2d.findAllMatches("**/+TextNode")
for i in elements:
    i.node().setText('New')
    pass

base.run()

The solution to this problem, use node()

A similar problem. In this situation, really need to use the setup?

import direct.directbase.DirectStart
from direct.gui.DirectGui import DirectButton

Button = DirectButton(text = 'Demo', scale = 0.07)

# Working
#Button['text'] = 'New'

#Does not work
elements = render2d.findAllMatches("**/-PGButton")
for i in elements:
    #i.node()['text'] = 'New'

base.run()

You need to pass mayChange=True to the OnscreenText, this is an optimization, because otherwise the onscreen text assumes you are not going to change the text. I believe similar applies to the direct button.

Also see panda3d.org/manual/index.php/OnscreenText

The problem is that findAllMatches () returns the NodePath. A need OnscreenText type.

It appears that the reference to an instance of this class does not store the unit, as this class constructor. It is in python. In the book honestly and openly say it. A better use for tasks that require more flexibility in the lower classes, for example TextNode etc.

Yes, this is a problem with all classes that inherit from NodePath (which is why it’s considered an anti-pattern), since NodePaths aren’t actually stored in the scene graph.

You can still manipulate the underlying TextNode, though, like this:

elements = render2d.findAllMatches("**/+TextNode")
for i in elements:
    i.node().setText('New')