How can i add attribute to an object in Lua? - object

I am trying to add an attirubute to objects that i created.Here i created bird display objects but i want to add those birds a spesific attiribute like typeOfBird and then i want to reach those attiributes like bird.typeOfBird . How can i do that?
module(...,package.seeall)
function new(params)
local bird=display.newImage(params.img,params.x,params.y)
function bird:touch(event)
local t = event.target
local phase = event.phase
if "began" == phase then
-- Make target the top-most object
local parent = t.parent
parent:insert( t )
display.getCurrentStage():setFocus( t )
t.isFocus = true
elseif t.isFocus then
if "moved" == phase then
t.x = event.x
t.y = event.y
elseif "ended" == phase or "cancelled" == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
end
end
return true
end

It looks like bird objects are already simple lua tables,
so you can just get and set the values as normal. So for example you could add lines like:
if self.typeOfBird == "gull" then ... end
and
self.typeOfBird = "parrot"
to your bird:touch function.
Or
bird.typeOfBird = "gull"
in your new function.

Related

Can't get the text from LineEdit to pass to a function

Context:
I click on a button -> a WindowDialogue appears -> there are 2 LineEdit Nodes and a button
Supposed procedure:
I fill these LineEdits, press the button, and the function tied to the button receives the texts from the LineEdits (and creates a dictionary key-value pair).
Problem:
The texts from the LineEdits do not pass down to the function (through connect()).
I tried passing the text directly with LineEdit.text. I tried writing it in a different variable and passing the variable. The debug shows the function is getting executed (no problem with that), but the strings passed from the LineEdits are always empty. Somehow, it worked for some time when I explicitly pressed ENTER after filling the LineEdits. But after I tried to fix the aforementioned problem, it stopped working altogether.
P.S. Everything I mentioned is created dynamically through the code, if that matters.
Code:
#Declaring the variables
var temp_text_key = ""
var temp_text_value = ""
#Function to show up a dialogue window with LineEdits and Confirm button
func _on_add_new_property(dict: Dictionary):
temporal_window_dialogue = WindowDialog.new()
temporal_window_dialogue.rect_min_size = Vector2(410,90)
temporal_window_dialogue.resizable = true
temporal_window_dialogue.popup_exclusive = true
temporal_window_dialogue.window_title = "Adding new property to %s" % get_dict_name_by_id(professions, dict["id"])
var le_key = LineEdit.new()
le_key.placeholder_text = "Name of the property"
le_key.hint_tooltip = "Name of the property"
le_key.connect("text_changed", self, "_on_add_new_prop_text_entered", ["key"])
var le_value = LineEdit.new()
le_value.expand_to_text_length = true
le_value.placeholder_text = "Value of the property"
le_value.set("custom_constants/minimum_spaces", 36)
le_value.hint_tooltip = "Value of the property"
le_value.connect("text_changed", self, "_on_add_new_prop_text_entered", ["value"])
var lab = Label.new()
lab.text = "Should the Value become a Dictionary?"
var check_bt = CheckBox.new()
var vbox = VBoxContainer.new()
var grid_container = GridContainer.new()
grid_container.columns = 2
var accept_bt = Button.new()
accept_bt.text = "Confirm"
temporal_window_dialogue.add_child(vbox)
vbox.add_child(grid_container)
grid_container.add_child(le_key)
grid_container.add_child(le_value)
grid_container.add_child(lab)
grid_container.add_child(check_bt)
vbox.add_child(accept_bt)
grid_container.set("custom_constants/vseparation", 5)
grid_container.set("custom_constants/hseparation", 5)
check_bt.connect("pressed", self, "_on_check_dict_pressed")
popup_window.add_child(temporal_window_dialogue)
temporal_window_dialogue.connect("popup_hide", self, "_on_close_specific_codegenerated_popup", [temporal_window_dialogue])
temporal_window_dialogue.popup_centered()
accept_bt.connect("pressed", self, "_on_add_new_property_confirmation", [dict, temp_text_key, temp_text_value])
#Function to create a new key/value pair in a dictionary
func _on_add_new_property_confirmation(dict: Dictionary, prop_name: String, prop_value: String):
if prop_name == "" or prop_value == "":
send_message_to_console("Neither of the two can be empty", 3)
return
if add_dictionary_flag:
dict[prop_name] = {
prop_value: {
"id": get_free_local_id_for_dict(dict)
}
}
elif !add_dictionary_flag:
if keywords_for_dictionaries.has(prop_name):
send_message_to_console("Only Dictionary items can become %s" % prop_name)
dict[prop_name] = prop_value
temp_text_key = ""
temp_text_value = ""
#Optional function to write the text from LineEdits to the variables
func _on_add_new_prop_text_entered(new_text, key_or_value):
if key_or_value == "key":
temp_text_key = new_text
elif key_or_value == "value":
temp_text_value = new_text
You mentioned using 'LineEdit.text', but have you tried the following?
var text = LineEdit.get_text()
If this doesn't help, please update your original post to include code examples.

Jupyter Notebook HOw can i assign a default value to datepicker and sort the time within the selected date?

I can try to set condition some data that is within the time picker in the datepicker. I got two problem
MY code was
def show_filter_date(start ,end):
print(start_dater.value)
print(end_dater.value)
time_df = (id_one[(id_one['_source.timestampstring']>pd.to_datetime(start))&(id_one['_source.timestampstring']<pd.to_datetime(end))])
#print(time_df.head(20))
# time_df = (id_one[(id_one['_source.timestampstring']>pd.to_datetime(start_dater.value))&(id_one['_source.timestampstring']<pd.to_datetime(end_dater.value))])
time_df.head(20)
layout = widgets.Layout(width='auto', height='40px')
start_dater = widgets.DatePicker(description='Pick a Start Date',disabled=False)
end_dater = widgets.DatePicker(description='Pick an End Date',disabled=False )
#display(widgets.HBox((start_dater, end_dater)))
#display(start_dater)
#display(end_dater)
#id_one.head()
#combine_date = widgets.HBox((start = start_dater, end = end_dater))
#country_selector = widgets.Dropdown(
interact(show_filter_date,start = start_dater , end = end_dater)
everytime i run the code it show Error
"Invalid comparison between dtype=datetime64[ns] and NoneType"
I have tried to assign default value like
start_dater = widgets.DatePicker(description='Pick a Start Date',disabled=False, year = 2020 ,month = 12, day = 1)
but it won't change to 2020/12/01
So, how can I get a value other than null?
I fail in interact for the datepicker in which
A) print(time_df.head(20))
B)
time_df = (id_one[(id_one['_source.timestampstring']>pd.to_datetime(start_dater.value))&(id_one['_source.timestampstring']<pd.to_datetime(end_dater.value))])
time_df.head(20)
Only (A) can be "interact" or "refresh" when I pick a day but not (B)
And for Question 2, when I put time_df.head(20) in the NEXT CELL it does work tho.......
But what i want is to show the result like in time_df
I would appreciate if any help
the id_one is something like
Index _source.hdrrId _source.hdrfId _source.hdrType \
199 1300 1234 1
_source.timestampstring
199 2020-11-06 09:36:04.800
Thanks!
Jeff
I replicated your first error with
id_one = pd.DataFrame(pd.date_range('20200101','20200202'), columns = ['_source.timestampstring'])
This is because you did not set a default value for the DatePicker. The value is None by default hence the error. Here is the fix (value argument is the default value):
start_dater = widgets.DatePicker(description='Pick a Start Date',disabled=False, value = datetime.date(2020,1,1))
end_dater = widgets.DatePicker(description='Pick an End Date',disabled=False, value = datetime.date(2020,2,1))
I cannot replicate your second error. My guess is you put print before the time_df = statement. You need to put the print after the line that calculates time_df

Display bug when label contain a expression

I have this function who supposed to change the label of polygon (code below), where "nom_com" and "statutpro" are fields in a layer.
def ETIQUETAGE(self):
layer = self.COUCHE_DEPARTEMENT_SELECTIONNEE() #return a vector layer
deco = QgsPalLayerSettings()
deco.enabled = True
isExpression = True
if self.ChoixEtiquetage.currentText() == "COMMUNE":
deco.fieldName = '\'nom :\' +"nom_com"'
if self.ChoixEtiquetage.currentText() == "COMMUNE ET STATUT PROSPECTION":
deco.fieldName = '"nom_com" + \'\\n\' +"statutpro"'
labeler = QgsVectorLayerSimpleLabeling(deco)
layer.setLabeling(labeler)
layer.setLabelsEnabled(True)
layer.triggerRepaint()
When I run it everything ok (i don't have any error), the problem is for the display. The function change the label charateristic in the properties window but there is no display until I press aply in the properties window.
When I put only one argument the display work perfectly. for example
deco.fieldName = "nom_com"
Is there a particular syntax when it's a expression ?
I just see where my error was, it was a syntaxe error.
If the label is expression based we must put
deco.isExpression
for the plugin to display something in the canvas
def ETIQUETAGE(self):
layer = self.COUCHE_DEPARTEMENT_SELECTIONNEE() #return a vector layer
deco = QgsPalLayerSettings()
deco.enabled = True
deco.isExpression = True
if self.ChoixEtiquetage.currentText() == "COMMUNE":
deco.fieldName = "concat('nom : ', nom_com)"
if self.ChoixEtiquetage.currentText() == "COMMUNE ET STATUT PROSPECTION":
deco.fieldName = "concat('nom : ', nom_com, '\\n', 'Statut prospection : ', statutpro)"'
labeler = QgsVectorLayerSimpleLabeling(deco)
layer.setLabeling(labeler)
layer.setLabelsEnabled(True)
layer.triggerRepaint()
hope it will help people

How to go to first line of a function if a condition is not satisfied in python?

I want to got First line of the function goToSignUpActivit() if isAllInputValid == False
from CustomUtil import *
from Register import *
def goToSingUpActivity():
fName = input("Enter your First Name:")
lName = input("Enter your last name:")
mobileNum = input("input your mobile number")
role = input("Select your role s: for staff p: for patient:")
isFNameValid = validateInput(fName)
isLNameValid = validateInput(lName) // this function in CustomUtil package
isRoleValid = False
if (role in ["s","p","S","P"]):
isRoleValid = True
isMobileNumValid = validateMobilNum(mobileNum)// this function in CustomUtil package
isAllInputValid = False
if (isFNameValid and isLNameValid and isRoleValid and isMobileNumValid) :
isAllInputValid = True
if (isAllInputValid) :
isAllInputValid = True
if role in ["s","S"]:
registerAsStaff(fName,lName,mobileNum)// this function in Register package
return
elif role in ["p","P"]:
registerAsPatient(fName,lName,mobileNum)// this function in Register package
return
while(not isAllInputValid):
if(input("you want to exit y or n:") in ["y","Y"]):
return
goToSingUpActivity()
Above code put goToSingUpActivity() into the stack while isAllInputValid become true.
After I enter all input correctly stack pop goToSingUpActivity() one bye one.
What I need here is after isAllInputValid becomes true, clear all goToSingUpActivity() from stack.
If above solution not possible, is there any other way to modifie the code?
Edit: I got a solution by making isAllInputValid global and put the while loop outside the function after calling goToSingUpActivity().
You can use a while statement (WARNING to don't create a while(true), give to the user an opportunity to cancel his action !).
def goToSingUpActivity():
 isAllValid = False
 while(!isAllValid):
#your inputs stuff
if(isFNameValid and isLNameValid and isRoleValid and isMobileNumValid):
   isAllValid = True
 #rest of the function

Corona + objects are not cleared between levels despite removeSelf + set to nil

I have multilevel game and all my objects stay 'empty' in memory between levels
what i mean is that if I set physics to hybrid, when i come again in the level, (or another level) it shows a box but without the picture. (and physics act on these empty boxes)
in the destroyScene I have made sure they are all
myObj:removeSelf()
myObj = nil
and i print a message to prove that it actually does it.
Also in the menu in the enterScene, just in case I do a
local prior_scene = storyboard.getprevious()
storyboard.purgescene( prior_scene )
and also tried a
storyboard.removeAll()
and even a
storyboard.purgeOnSceneChange = true
nothing works when i go to the next level, or into the same level again, all my previous objects are still here, I just don't get it
ok, it's gonna be a bit long but here the entire level. it does go through the destroyscene but somehow the display objects are not removed.
-- scene5
----------------------------------------------------------------------------------
local storyboard = require( "storyboard" )
local scene5 = storyboard.newScene()
function scene5:createScene( event )
local group = self.view
puppetJColCount = 0
print ("createScene5", puppetJColCount)
-----------------------------------------------------------------------------
-- CREATE display objects and add them to 'group' here.
-- Example use-case: Restore 'group' from previously saved state.
local physics = require("physics")
physics.start()
--physics.setScale(50)
puppetT_outside = false
puppetJ_outside = false
end -- scene -------------------------
-- set and release the catapult for puppetT
function arm_puppetT(event)
if event.phase == "began" then
display.getCurrentStage():setFocus(puppetT)
arming_puppetT = true
elseif event.phase == "moved" then
puppetT.x = event.x
puppetT.y = event.y
elseif event.phase == "ended" then
puppetT:applyLinearImpulse(event.xStart - event.x, event.yStart - event.y, puppetT.x, puppetT.y)
display.getCurrentStage():setFocus(nil)
arming_puppetT = false
end
end -- arm_puppetT ----------------------------------------------------------------------------
function build_puppetT()
-- setup puppetT
puppetT = display.newImage("assets/t-head-57-78.png")
puppetT.x = 80
puppetT.y = 100
physics.addBody(puppetT,"dynamic",{density=1.0, friction =0.3, bounce=0.2})
-- setup catapult event for arming puppetT
puppetT:addEventListener("touch", arm_puppetT)
end -- build_puppetT
function build_puppetJ_wall()
puppetJColCount = puppetJColCount + 1 -- how many columns of puppetJ
puppetJIJ = {} -- define puppetJ as an array
ij = 0
ipuppetJtot = 0
--puppetJColCount = 1
print ("build_puppetJ_wall puppetJColCount>" , puppetJColCount);
for i=1, 4 do
for j=1, puppetJColCount do
ij = ij + 1 -- # of puppetJs on the screen
ipuppetJtot = ipuppetJtot + 1
puppetJIJ = display.newImageRect("assets/j-head-70-75.png",80,75)
puppetJIJ.x = 600 + j*22
puppetJIJ.y = 100 + (puppetJIJ.height /2 * (i -1))
physics.addBody(puppetJIJ,"dynamic",{density=1.0,friction=0.3,bounce=0.2,isSensor=false,radius = var})
end
end
print ("building puppetJs #:" ,ipuppetJtot)
end -- build_puppetJ_wall -------------------------------------------------------------
function every_frame( event )
end -- every_frame --------------------------------------------------------------------
--reset level
function tap_reset_level(event)
puppetT:applyLinearImpulse(0, 0, 0, 0) -- stop the kick
print "restarting physics?"
puppetT:setLinearVelocity( 0, 0 ) -- stop the speed
puppetT.x = 80
puppetT.y = 100
for ij = 1,ipuppetJtot do
if (puppetJIJ) then
puppetJIJ:removeSelf()
puppetJIJ = nil ------
end
end
puppetT:removeSelf()
puppetT = nil
build_puppetJ_wall()
build_puppetT()
puppetT_outside = false
puppetJ_outside = false
-- physics.addBody(puppetT,"dynamic",{density=1.0, friction =0.3, bounce=0.2})
-- puppetT:addEventListener("touch", arm_puppetT)
--physics.start()
end -- tap_reset_level -------------------------------------------------------------------------
function tap_main_menu(event)
print ("going to main menu")
Runtime:removeEventListener("enterFrame", every_frame)
for ij = 1,ipuppetJtot do
if (puppetJIJ) then
puppetJIJ:removeSelf()
puppetJIJ = nil ------
end
end
if (puppetT) then
puppetT:removeSelf()
puppetT = nil
end
-- scene5:exitScene(scene5)
storyboard.gotoScene( "menu" )
end -- tap_main_menu ---------------------------------------------------------------------------------
-- ======================================================================================
-- Called immediately after scene has moved onscreen:
function scene5:enterScene( event )
local group = self.view
-----------------------------------------------------------------------------
-- INSERT code here (e.g. start timers, load audio, start listeners, etc.)
-- group:insert( reset_btn )
-- load background
print ("enterScene scene5 " , puppetJtot)
background = display.newImage("assets/parliament-1200-800.png",0,0)
--create reset level button
reset_btn = display.newImageRect( "assets/btn_reset_128.png", 50,50)
reset_btn.x = 50
reset_btn.y = 50
--create main menu button
main_menu_btn = display.newImageRect( "assets/btn_home_128.png", 50,50)
main_menu_btn.x = 100
main_menu_btn.y = 50
-- show the level
local myText = display.newText( "Level 5", display.contentWidth - 60, 50, "Helvetica", 24 )
myText:setTextColor(255, 255, 255)
-- insert(floor);
floor = display.newRect(20,display.contentHeight - 40,display.contentWidth - 40 ,10)
physics.addBody(floor,"static",{density=1.0, friction =-0.3,bounce=-0.2,isSensor=false})
-- build puppetT
build_puppetT()
print ("width=" , display.contentWidth , "height=",display.contentHeight)
-- setup puppetJs
build_puppetJ_wall()
-- everything happens in everyframe function
Runtime:addEventListener("enterFrame", every_frame)
--add reset event
reset_btn:addEventListener( "tap", tap_reset_level )
--add mainmenu event
main_menu_btn:addEventListener( "tap", tap_main_menu )
end -- scene:enterScene ----------------------------------------------------------------
-- ======================================================================================
-- Called when scene is about to move offscreen:
function scene5:exitScene( event )
local group = self.view
print "scene:exitScene5"
-----------------------------------------------------------------------------
-- INSERT code here (e.g. stop timers, remove listeners, unload sounds, etc.)
end -- exitScene
-- Called prior to the removal of scene's "view" (display group)
function scene5:destroyScene( event )
local group = self.view
Runtime:removeEventListener("enterFrame", every_frame)
puppetJColCount = 0
if (reset_btn) then
print ("destroyScene5 - removing tap_reset_level")
reset_btn:removeEventListener( "tap", tap_reset_level )
reset_btn:removeSelf()
end
reset_btn = nil
if (main_menu_btn) then
main_menu_btn:removeEventListener( "tap", tap_main_menu )
main_menu_btn:removeSelf()
end
main_menu_btn = nil
for ij = 1,ipuppetJtot do
if (puppetJIJ) then
puppetJIJ:removeSelf()
end
puppetJIJ = nil ------
end
if (puppetT) then
puppetT:removeSelf()
end
puppetT = nil
scene5 = nil
end -- destroyScene ------------------------------------------------------------
scene5:addEventListener( "createScene", scene5 )
scene5:addEventListener( "enterScene", scene5 )
scene5:addEventListener( "exitScene", scene5 )
scene5:addEventListener( "destroyScene", scene5 )
---------------------------------------------------------------------------------
return scene5
update:
Hi #DevfaR
Ha, I have restarted from scratch with the corona template and figured out a few things:
1) the exitScene/destroyScene actually does something if the local group is used to group display objects. it removes the display group !
not really obvious as there is only one declaration in it, no code as such
2) the reason why I had so much of removeSelf of objects all over the place is because nothing was working. So I tried pretty much everything under the web.
3) And the reason why it didnt work is because I was creating my display objects into a function. and somehow the display group is not passed there. if I move the code into the createScene function then indeed it is all cleared up when going to the next scene.
problem is .. I really would like to group my puppetCreation code !
e.g.
function scene:createScene( event )
local group = self.view
local physics = require("physics")
physics.start()
background = display.newImage("assets/bckg.png",0,0)
group:insert(background)
createPuppet1(group)
createPuppet2(group)
end
function createPuppet1(group)
puppet1= display.newImage("assets/puppet1.png",0,0)
group:insert(puppet1)
end
function createPuppet2(group)
puppet2= display.newImage("assets/puppet2.png",0,0)
group:insert(puppet2)
end
I passed (group) because the function createPuppet doesnt let me specify
local group = self.view
my email address is edualczatebed#gmail.com
thank you for your help
there's a lot of bug in your code the way you implement it is not good because when you go to a scene and then you switch to another scene your removing all of the object on the destroyScene together with it's listener which is not very efficient i cannot point out what's causing the problem because like i said there is a lot of bug in your code. i think you didn't quite understand how to use a storyboard on Corona. to give you an idea on how will you solve your problem i will implement some code for you to understand that even if you do not remove the object on destroyScene you can remove the object via it's on display groups.
local rectangle
local circle
local function nextScene(event)
storyboard.gotoScene( "scene_2", "fade", "500")
end
-- Called when the scene's view does not exist:
function scene:createScene( event )
local group = self.view
-----------------------------------------------------------------------------
rectangle = display.newRect(100,100,100,100)
rectangle:setFillColor(255,0,0)
rectangle.x = 100
rectangle.y = 100
circle = display.newCircle(100,100,50)
circle.x = 250
circle.y = 100
circle:setFillColor(0,255,0)
--inserting all of your object into display group so that if you destroy the scene the display group will be remove
group:insert(rectangle)
group:insert(circle)
-----------------------------------------------------------------------------
end
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view
-----------------------------------------------------------------------------
rectangle:addEventListener("tap", nextScene)
circle:addEventListener("tap", nextScene)
-----------------------------------------------------------------------------
end
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
local group = self.view
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
end
-- Called prior to the removal of scene's "view" (display group)
function scene:destroyScene( event )
local group = self.view
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
end
as you can see i create 2 object the rectangle and circle after i created the objects insert it to group then on enterScene i added a tap listener which will go to the second scene if i tap the object. notice that i didn't bother to remove the object and listener on destroyScene when i go to the scene_2 that is because when i insert the object to the display group whenever i change the scene it will always remove the object. so after moving to the next scene you can either purged the last scene or completely remove it so when you get back to that scene it will recreate the object.
hope this can help you solve your problem

Resources