Global Variable doesn't work on CoreMessage?
-
Hi,
I have two main classes. One for
TreeView
and the other forGeDialog
.I have inserted
c4d.SpecialEventAdd()
inTreeview
The event triggers well under theCoreMessage
ofGeDialog
.The problem is global variable is not being updated under the
CoreMessage
In the illustration below, the console always prints "images".
It should, however, be changed to whatever Tree Item is selected.
https://www.dropbox.com/s/gjdvda8n4b16rs9/c4d264_global_variable_doesn't_work_on_core_message.mp4?dl=0You can check the
CoreMessage
function in the source code below:
https://www.dropbox.com/sh/lpfpmux073toork/AACTxFpGmMK2MpgoCI0N-3Eba?dl=0Is there a way around this?
-
Please use the Markdown to list your code, as mentioned here (link = https://developers.maxon.net/forum/topic/10953/how-to-post-questions). It's easier for anyone to look at your code in your topic, instead of following a link. Thanks.
-
Hi,
cur_folder
is not aglobal
variable, but a module level variable. The only place where you modifycur_folder
is inTreeData.Select
. You will need to test if that branch of the method is ever executed.On a side note: Never use
global
variables, because they are the devils work and module level variables are also a dangerous thing in a threaded environment (but you should be safe here, since everything should normally run on the main thread in your code).Cheers,
zipit -
Thanks for the response
@C4DS
I usually put markdowns on my code whenever I ask questions.
It's just there are dependencies on the code, so I didn't.
Anyway, here is theCoreMessage
sectiondef CoreMessage(self, id, msg): if id==PLUGIN_ID: #Fired by the main thread... print cur_folder return True return gui.GeDialog.CoreMessage(self, id, msg)
@zipit
RE:
cur_folder
is not agloba
l variable
Oh but I actually declared it before any Class or Functions.
The variable is at the top under theimport
statements.RE: You will need to test if that branch of the method is ever executed.
Whenever I print thecur_folder
inside theclass Tree Data > def Select
, it works as expected (i.e. it prints a different variable whenever I click a folder)It's on the
class GeDialog>def CoreMessage
that for some reason stuck at the initial variable declaration (i.e. "images")Let me know if you need further clarification.
-
Hi,
I was just pointing out that
global
has slightly different meaning in Python than in other languages.global
is a keyword with which you can shadow a variable of an inner scope with an variable of an outer scope. Your variable is neitherglobal
nor really a variable, but an attribute bound to a module.When you assign the name to
cur_value
inSelect
, you do this to a variable calledcur_value
in the scope of the methodSelect
, not to the attribute of the same name of the module.SOME_ATTRIBUTE = "Bob is your uncle" class MyObject(): def do(self): """ """ SOME_ATTRIBUTE = "This won't work" def do_global(self): """ """ # Bad, really bad! Do not do this. global SOME_ATTRIBUTE SOME_ATTRIBUTE = "This will work" obj = MyObject() print SOME_ATTRIBUTE obj.do() print SOME_ATTRIBUTE obj.do_global() print SOME_ATTRIBUTE
Bob is your uncle Bob is your uncle This will work [Finished in 0.1s]
The correct way would either be to bind your
cur_folder
to an object over which you have more control (a class or an instance of class) or just sendcur_folder
along with the message as message data.Cheers,
zipit -
@zipit
Thanks for the warning.
Yep, the addingclass or an instance of class
seems to work as expected.
I ended up using dict/list since I have to store the variable along with its designated path.RE: just send cur_folder along with the message as message data
I'm not sure how to do this. I'll just probably create a separate thread for this one.Thanks again for help.
-
@bentraje I don't have that much to add on your topic since I think @zipit already explained everything nicely.
In any case some good resource for you about how global variable works in Python Global keyword in Python and Mutable vs Immutable Objects in Python.
Regarding your last question, I think you should open a new topic, but the short answer there is no way to pass directly a variable with a MessageData, the best way is to use a scope accessible by both part and store this variable in this shared scope (can be global or any other).
Cheers,
Maxime.