Invalid set index 'texture' (on base: 'null instance') - gd

Invalid set index 'texture' (on base: 'null instance') with value of type 'StreamTexture'.
extends Panel
var ItemClass = preload("res://Item.tscn")
var item = "res://Blue Jeans.png"
func _ready():
if randi() % 2 == 0:
item = ItemClass.instance()
add_child(item)
extends TextureRect
func _ready():
if randi() % 2 == 0:
$TextureRect.texture = load("res://Blue Jeans.png")
else:
$TextureRect.texture = load("res://Brown Boots.png")
I followed the exact tutorial on YT https://www.youtube.com/watch?v=FHYb63ppHmk
but it seems to debug differently.

This line:
$TextureRect.texture = load("res://Blue Jeans.png")`
Loads a png as a StreamTexture using load, and tries to set it to the texture property of whatever $TextureRect is.
But the error says that there is no texture property on a null instance. Thus, the problem is that $TextureRect is a null instance.
So what does the expression $TextureRect do? It is equivalent to get_node("TextureRect"). In other words it is trying to get a child node called "TextureRect". And it is getting null…
Does the node on which the script is attached have a child node called "TextureRect"? You didn't share how the scene tree looks like, but I suspect it does not.
The script you shared says extends TextureRect, thus the script would be attached to a TextureRect. However, that is not what they do in the tutorial. In the tutorial the script is attached to a Node2D that has the TextureRect as child. You can see that at 4:10 on the tutorial video.
If you want to set the texture of the node on which the script is attached, set texture directly:
texture = load("res://Blue Jeans.png")`
Or if you rather be explicit, use self:
self.texture = load("res://Blue Jeans.png")`
On the other hand, if you are trying to follow the tutorial, then put the script on a node that has the TextureRect as a child (called "TextureRect"), and there $TextureRect would work.

Related

How to change the XFade on a transition node in script?

I'm currently learning Godot and my textbook seems to be a bit out of date as it still uses the deprecated AnimationTreePlayer. So I've had to figure out AnimationTree on my own. The exercise for this lesson talks about changing the XFade for the transition node to a random value when the player presses the "up" key but I cannot for the life of me figure out how to do it. I see in the documentation that AnimationNodeTransition has a set_cross_fade_time(value) method but how do I get to it? How do I even access the tranisition node in the script? I've tried things like $AnimationTree/Transition and $AnimationTree["parameters/Transition"] but nothing I've tried works.
My script is currently on the root node and the node tree looks like this:
Sprite [script is here]
AnimationPlayer
AnimationTree
Let us say you have your AnimationTree with the AnimationPlayer set on the anim_player property. And the tree_root of the AnimationTree is an AnimationNodeBlendTree, where - among other nodes - you have an AnimationNodeTransition.
As you are aware, we can get some "paramters" of the AnimationTree, they should appear in the Inspector Panel. And there you should find this one:
$AnimationTree.get("parameters/Transition/current")
Where "Transition" is the name of the node in the AnimationNodeBlendTree. But there isn't a parameter for the xfade_time.
Instead we will get the root of the AnimationTree (in other words, the AnimationNodeBlendTree) like this:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
Then we can get the nodes like this:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
var node := blend_tree.get("nodes/NodeName/node")
By the way, if you change "/node" to "/position" you get a Vector2 with the position of the node on the editor.
So, let us say we want a node called "Transition", which is our AnimationNodeTransition. We do this:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
var transition := blend_tree.get("nodes/Transition/node") as AnimationNodeTransition
And finally we can access xfade_time. Set a random value you said? This should do:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
var transition := blend_tree.get("nodes/Transition/node") as AnimationNodeTransition
transition.xfade_time = rand_range(0.0, 120.0)
Or as a one line:
$AnimationTree.tree_root.get("nodes/Transition/node").xfade_time = rand_range(0.0, 120.0)
Be aware that the value of xfade_time is the number of seconds for the transition. So setting 120 give you a two minutes transition.

My toplevel window in tkinter is no longer being destroyed. It was working fine until I tried changing other aspects of my function

I'm trying to get a popup window to display random text and a picture every time a button is pressed in tkinter. My original code was going to use an if/elif statement to do this. It worked as intended but I thought it might be easier to pair the data in a dictionary since there would be 50 elif statements otherwise (is it frowned upon to use so many? I actually found it easier to read).I was able to get this working but now the toplevel window in tkinter is not being destroyed like it was in the original function. A new Label is just being created on top of it and I can't figure out why. The function code is below. Thanks in advance, any help would be appreciated!
def Add_Gemstone2():
global Addstone
#destroy the previous window if there is one.
try:
AddStone.destroy()
except(AttributeError, NameError):
pass
#create the window.
AddStone=Toplevel()
AddStone.configure(bg='White', height=200, width=325)
AddStone.geometry('325x180+10+100')
# add gemstones to list from file.
gem_stones = open('gemstones.txt')
all_gem_stones = gem_stones.readlines()
gemstones = []
for i in all_gem_stones:
gemstones.append(i.rstrip())
# Add pictures to list.
path = r'C:\Users\Slack\Desktop\PYTHON WORKS\PYTHON GUI PROJECT\gems'
gempictures = []
# r=root, d=directories, f = files
for r,d,f in os.walk(path):
for file in f:
if '.gif' in file:
gempictures.append(os.path.join(r, file))
#create dictionary from lists.
gemdiction = dict(zip(gemstones, gempictures))
key, val = random.choice(list(gemdiction.items()))
# create the labels.
glbl1 = Label(AddStone, text=key, bg='gold', wraplength=300)
glbl1.pack()
image = ImageTk.PhotoImage(Image.open(val))
glbl2 = Label(AddStone, image=image)
glbl2.image = image
glbl2.pack()

Using Javascript for Automation to copy cells in Numbers

I want to use JXA to automate some updating of Numbers spreadsheets. For example, copying a range of cells from one spreadsheet to another one with a different structure.
At this point, I'm just testing a simple program to set or read the value of a cell and I can't get this to work.
When I try to set a value I get "Error -1700: Can't convert types." and when I try to read a value I get back a [object ObjectSpecifier] rather than a text or number value.
Here's an example of the code:
Numbers = Application('Numbers')
Numbers.activate()
delay(1)
doc = Numbers.open(Path('/Users/username/Desktop/Test.numbers'))
currentSheet = doc.Sheets[0]
currentTable = currentSheet.Tables[0]
console.log(currentTable['name'])
console.log(currentTable.cell[1][1])
currentTable.cell[1][1].set(77)
When I run this, I get and output of [object ObjectSpecifier] for the two console.logs and then an error -1700: Can't convert types when it tries to set a cell.
I've tried several other variations of accessing or setting properties but can't get it to work.
Thanks in advance,
Dave
Here is a script that sets and gets a cell's value and then sets a different cell's value in the same table:
// Open Numbers document (no activate or delay is needed)
var Numbers = Application("Numbers")
var path = Path("/path/to/spreadsheet.numbers")
var doc = Numbers.open(path)
// Access the first table of the first sheet of the document
// Note:
// .sheets and .tables (lowercase plural) are used when accessing elements
// .Sheet and .Table (capitalized singular) are used when creating new elements
var sheet = doc.sheets[0]
var table = sheet.tables[0]
// Access the cell named "A1"
var cell = table.cells["A1"]
// Set the cell's value
cell.value = 20
// Get the cell's value
var cellValue = cell.value()
// Set that value in a different cell
table.cells["B2"].value = cellValue
Check out the Numbers scripting dictionary (with JavaScript selected as the language) to see classes and their properties and elements. The elements section will show you the names of elements (e.g. the Document class contains sheets, the Sheet class contains tables, and so on). To open the scripting dictionary, in Script Editor's menu bar, choose Window > Library, and then select Numbers in the library window.
In regards to the logging you were seeing - I recommend using a function similar to this:
function prettyLog(object) {
console.log(Automation.getDisplayString(object))
}
Automation.getDisplayString gives you a "pretty print" version of any object you pass to it. You can then use that for better diagnostic logging.

mayavi volume animation not updating

I’m trying to animate a Mayavi pipeline volume:
src = mlab.pipeline.volume(mlab.pipeline.scalar_field(data),vmin=.1*np.max(data),vmax=.2*np.max(data))
that is combined in the pipeline by another dataset represented as a cut plane.
However, I can’t get the volume visualization to update - only the first frame shows up. The animation is stepping through the data correctly (I get different values of the np.max(data[t]) below) but nothing in the visualization changes.
My understanding is that mlab_source_set should re-render correctly, and there’s nothing on the web anywhere that describes this (as far as I can tell).
The animation looks like:
#mlab.show
#mlab.animate(delay=250,ui=True)
def anim(src,data,tax,fig):
"""Animate."""
t = 0
nt = len(tax)
while 1:
vmin = .1*np.max(data[t])
vmax = .2*np.max(data[t])
print 'animation t = ',tax[t],', max = ',np.max(data[t])
src.mlab_source.set(scalar = mlab.pipeline.scalar_field(data[t]), vmin=vmin,vmax=vmax)
t = mod(t+1,nt)
yield
Any thoughts?

ActionScript 2 loadClip depth

When I use:
loader = new MovieClipLoader();
_root.createEmptyMovieClip("level1",getNextHighestDepth());
_root.level1.createEmptyMovieClip("image",getNextHighestDepth());
loader.loadClip("http://someimage.jpg",_root.level1.image);
...it works and the image shows up.
But when I use:
loader = new MovieClipLoader();
_root.createEmptyMovieClip("level1",getNextHighestDepth());
_root.level1.createEmptyMovieClip("level2",getNextHighestDepth());
_root.level1.level2.createEmptyMovieClip("image",getNextHighestDepth());
loader.loadClip("http://someimage.jpg",_root.level1.level2.image);
...the image doesn't show up. Can anyone tell me why? How can I make this work?
the depth you are supplying is going to be '1'. is that what you are expecting?
each movie clip has it's own set of depths, so the nextHighestDepth() of the newly create 'image' mc, will be 1. it should not prevent loading the image though.
As gthmb says, you should call getNextHighestDepth() on the same MovieClip as you do the createEmptyMovieClip() on. So your code example should be more like:
loader = new MovieClipLoader();
_root.createEmptyMovieClip("level1",_root.getNextHighestDepth());
_root.level1.createEmptyMovieClip("level2",_root.level1.getNextHighestDepth());
_root.level1.level2.createEmptyMovieClip("image",_root.level1.level2.getNextHighestDepth());
loader.loadClip("http://someimage.jpg",_root.level1.level2.image);
Also, I would recommend storing references to the created MovieClips, so you won't have to use the full path in each occurrence in the code, something in the lines of this:
loader = new MovieClipLoader();
var level1:MovieClip = _root.createEmptyMovieClip("level1",_root.getNextHighestDepth());
var level2:MovieClip = level1.createEmptyMovieClip("level2",level1.getNextHighestDepth());
var image:MovieClip = level2.createEmptyMovieClip("image",level2.getNextHighestDepth());
loader.loadClip("http://someimage.jpg",image);

Resources