omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Label not updating

    Pythonista
    4
    11
    208
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • timjhinton
      timjhinton last edited by ccc

      Hello, I need a little help here. I can’t figure out why my label isn’t updating. Essentially, I create a label that has a number value. That works fine. But, with a button push I bring up a modal scene and press another button. This option then dismisses the modal scene, the value that is displayed in the LabelNode is updating in value because it is written to another file, but the value that is being displayed isn’t updating to the new value. I’ll try to copy and paste the functions that I think are the most important.

      First, here is the LabelNode created in the setup() for the Scene:

      mad_spend_label = str(self.maddex_accounts[7])
      		self.Maddex_spending_amount = LabelNode(mad_spend_label, font=menu_button_font, color='black', position=(-(self.menu_bg.size.w/3), self.menu_bg.size.h/2 - 160), parent=self.menu_bg)
      

      This is the function that is called when said button is pushed:

      def run_weekly(self):
      		self.paused = True
      		self.run_weekly_scene = BudgetClasses.WeeklySubMenuScene("Weekly Payout", "Who gets paid?",["Both", "Maddex", "Ryker", "Back"])
      		self.present_modal_scene(self.run_weekly_scene)
      		self.run_weekly_scene = None
      		self.update_labels()
      

      Here is a function I created trying to get it to display the correct value:

      def update_labels(self):
      		self.maddex_accounts, self.ryker_accounts = BudgetClasses.TransMethod.get_budget_values()
      		self.Maddex_spending_amount.text = str(self.maddex_accounts[7])
      		self.Maddex_savings_amount.text = str(self.maddex_accounts[8])
      		self.Maddex_tithing_amount.text = str(self.maddex_accounts[9])
      		self.Ryker_spending_amount.text = str(self.ryker_accounts[7])
      		self.Ryker_savings_amount.text = str(self.ryker_accounts[8])
      		self.Ryker_tithing_amount.text = str(self.ryker_accounts[9])
      

      Here is the function that is called from the WeeklySubMenuScene that is presented:

      def weekly_both(self):
      		#[0 kid, 1 ID, 2 date, 3 desc, 4 begin_spend, 5 begin_save, 6 begin_tithe, 7 end_spend, 8 end_save, 9 end_tithe]
      		maddex_accounts, ryker_accounts = TransMethod.get_budget_values()
      		new_mad_accounts = self.apply_weekly(maddex_accounts)
      		new_ryk_accounts = self.apply_weekly(ryker_accounts)
      		TransMethod.send_mad_trans(new_mad_accounts)
      		TransMethod.send_ryker_trans(new_ryk_accounts)
      		self.dismiss_modal_scene()
      		self.paused = False
      

      So, when that function is run it is successful because the updated values are written to a separate file, but that updated value wont display. If I close the program and then start it again then it displays the updated value that is retrieved from the separate file. I’d like for the value of that LabelNode to update! Any help would be appreciated.

      cvp 1 Reply Last reply Reply Quote 0
      • cvp
        cvp @timjhinton last edited by

        @timjhinton It is very difficult to help you because your code has lost its indentation.

        If you want to insert code in your post, please use special button </>

        alt text

        A timjhinton 3 Replies Last reply Reply Quote 0
        • A
          artsemlaz @cvp last edited by

          @cvp I had the same problem, thanks

          1 Reply Last reply Reply Quote 0
          • timjhinton
            timjhinton @cvp last edited by ccc

            @cvp Ahh gotcha. I can do that. Here they are:

            mad_spend_label = str(self.maddex_accounts[7])
            		self.Maddex_spending_amount = LabelNode(mad_spend_label, font=menu_button_font, color='black', position=(-(self.menu_bg.size.w/3), self.menu_bg.size.h/2 - 160), parent=self.menu_bg)
            		self.account_values.append(self.Maddex_spending_amount)
            
            def run_weekly(self):
            		self.paused = True
            		self.run_weekly_scene = BudgetClasses.WeeklySubMenuScene("Weekly Payout", "Who gets paid?",["Both", "Maddex", "Ryker", "Back"])
            		self.present_modal_scene(self.run_weekly_scene)
            		self.run_weekly_scene = None
            		self.update_labels()
            
            def weekly_both(self):
            		#[0 kid, 1 ID, 2 date, 3 desc, 4 begin_spend, 5 begin_save, 6 begin_tithe, 7 end_spend, 8 end_save, 9 end_tithe]
            		maddex_accounts, ryker_accounts = TransMethod.get_budget_values()
            		new_mad_accounts = self.apply_weekly(maddex_accounts)
            		new_ryk_accounts = self.apply_weekly(ryker_accounts)
            		TransMethod.send_mad_trans(new_mad_accounts)
            		TransMethod.send_ryker_trans(new_ryk_accounts)
            		self.dismiss_modal_scene()
            		self.paused = False
            

            I even tried to manually update it with this function:

            def update_labels(self):
            		self.maddex_accounts, self.ryker_accounts = BudgetClasses.TransMethod.get_budget_values()
            		self.Maddex_spending_amount.text = str(self.maddex_accounts[7])
            		self.Maddex_savings_amount.text = str(self.maddex_accounts[8])
            		self.Maddex_tithing_amount.text = str(self.maddex_accounts[9])
            		self.Ryker_spending_amount.text = str(self.ryker_accounts[7])
            		self.Ryker_savings_amount.text = str(self.ryker_accounts[8])
            		self.Ryker_tithing_amount.text = str(self.ryker_accounts[9])
            

            Does that help?

            1 Reply Last reply Reply Quote 0
            • timjhinton
              timjhinton @cvp last edited by

              @cvp Well, that didn’t work how I hoped. So for the update_labels() and the other function that didn’t get quoted right there is really no indention. All of the code inside of the function definition is at the same indention.

              def update_labels(self):
              		self.maddex_accounts, self.ryker_accounts = BudgetClasses.TransMethod.get_budget_values()
              		self.Maddex_spending_amount.text = str(self.maddex_accounts[7])
              		self.Maddex_savings_amount.text = str(self.maddex_accounts[8])
              		self.Maddex_tithing_amount.text = str(self.maddex_accounts[9])
              		self.Ryker_spending_amount.text = str(self.ryker_accounts[7])
              		self.Ryker_savings_amount.text = str(self.ryker_accounts[8])
              		self.Ryker_tithing_amount.text = str(self.ryker_accounts[9]) 
              

              Like so. I think that clears it all up?

              cvp 3 Replies Last reply Reply Quote 0
              • cvp
                cvp @timjhinton last edited by cvp

                @timjhinton if you edit your post or another forum user quotes your post, we can see that the end triple back quotes stays at the end of the posted code. You have to put it at the begin of next line, by typing an enter where I've put the red arrow

                alt text

                So it becomes

                alt text

                1 Reply Last reply Reply Quote 0
                • cvp
                  cvp @timjhinton last edited by cvp

                  @timjhinton For me, it is almost impossible to understand your problem. Without the full code, it is very difficult to help you. Perhaps somebody else could help you in a better way. Sincerely sorry and ready to help. more if you provide the entire code

                  timjhinton 1 Reply Last reply Reply Quote 0
                  • timjhinton
                    timjhinton @cvp last edited by

                    @cvp Hmm I’m not exactly sure how to explain it differently. Simply put, I am creating a label and setting the value to a variable. When I update the value of that variable, the label is not updating. If I close out the program and open it back up then it displays the new, correct value.

                    I wonder if the issue is happening because I have it presenting a sub menu scene where the button is that calls the function that updates values and then I dismiss that scene. This is when I expect the label value to update.

                    Anyways, I’d be happy to send you the code via email or something for you to take a look?

                    cvp JonB 2 Replies Last reply Reply Quote 0
                    • cvp
                      cvp @timjhinton last edited by

                      @timjhinton said

                      Anyways, I’d be happy to send you the code via email or something for you to take a look?

                      Never a private mail in the forum.
                      Thus, if you could post the code in Github or another web site.

                      1 Reply Last reply Reply Quote 0
                      • JonB
                        JonB @timjhinton last edited by JonB

                        @timjhinton a few key points which will probably let you understand better what is happening:

                        1. button actions functions must return, before anything is displayed on the screen. That is because button actions are called in the main thread, and the UI, touch handling, etc all stops until your action returns.
                        2. present_modal_scene is NON Blocking. This isn't necessarily obvious from the docs, and often when one thinks of a modal dialogue, you think of something that waits until the dialogue is closed before proceeding.

                        Since it returns immediately, your update label function gets called immediately, before you have pressed the button in your modal scene

                        The way to handle this sort of thing is via a completion handler function, which is defined in your main scene, but the modal scene is responsible for calling when it is done. So you would set my_modal_scene.completion = self.update_labels (or, a local function that does whatever other cleanup needs to happen, unpaying your scene ,etc) then in your button handling method in your modal scene, you would call self.completion().

                        
                        def update_weekly(self):
                            self.paused = True
                            self.run_weekly_scene = BudgetClasses.WeeklySubMenuScene("Weekly Payout", "Who gets paid?",["Both", "Maddex", "Ryker", "Back"])
                        
                            def completion():
                                 self.run_weekly_scene = None
                                 self.update_labels()
                                 self.pause = False
                                
                            self.present_modal_scene(self.run_weekly_scene)
                            # weekly_scene must call completion on close or button press
                        
                        

                        You could also block waiting for the scene to close by using a threading.Lock, but then you need to make sure that your button action is decorated with in_background, so that the action returns immediately (in_background schedules the action on the background thread, exiting the main thread immediately). But this pattern can lead to unexpected behavior, since the background thread is shared sometimes, and you have to be careful to only ever use ont thing at a time on it. You can create your own threading.Thread, but that is more complicated. The "completion handler callback" shown above is thread safe and easy (which is why a lot of apple frameworks use that pattern as well). You just have to handle the "cleanup" code in a the completion handler, rather than after the call to present_modal_scene, and it will be called later by the modal scene.

                        1 Reply Last reply Reply Quote 0
                        • cvp
                          cvp @timjhinton last edited by

                          @timjhinton following @JonB advice, could you try to only change your program by preceding button action function with @ui.in_background

                          @ui.in_background				
                          def run_weekly(self):
                          		self.paused = True
                          		self.run_weekly_scene = BudgetClasses.WeeklySubMenuScene("Weekly Payout", "Who gets paid?",["Both", "Maddex", "Ryker", "Back"])
                          		self.present_modal_scene(self.run_weekly_scene)
                          		self.run_weekly_scene = None
                          		self.update_labels()
                          
                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post
                          Powered by NodeBB Forums | Contributors