• <small id='L4GjW'></small><noframes id='L4GjW'>

    <legend id='L4GjW'><style id='L4GjW'><dir id='L4GjW'><q id='L4GjW'></q></dir></style></legend>

    <i id='L4GjW'><tr id='L4GjW'><dt id='L4GjW'><q id='L4GjW'><span id='L4GjW'><b id='L4GjW'><form id='L4GjW'><ins id='L4GjW'></ins><ul id='L4GjW'></ul><sub id='L4GjW'></sub></form><legend id='L4GjW'></legend><bdo id='L4GjW'><pre id='L4GjW'><center id='L4GjW'></center></pre></bdo></b><th id='L4GjW'></th></span></q></dt></tr></i><div id='L4GjW'><tfoot id='L4GjW'></tfoot><dl id='L4GjW'><fieldset id='L4GjW'></fieldset></dl></div>

  • <tfoot id='L4GjW'></tfoot>
      <bdo id='L4GjW'></bdo><ul id='L4GjW'></ul>

        如何从线程更新 Kivy 元素?

        How do I update Kivy elements from a thread?(如何从线程更新 Kivy 元素?)
          <legend id='1Vqc4'><style id='1Vqc4'><dir id='1Vqc4'><q id='1Vqc4'></q></dir></style></legend>
            <bdo id='1Vqc4'></bdo><ul id='1Vqc4'></ul>

                <tbody id='1Vqc4'></tbody>

                1. <small id='1Vqc4'></small><noframes id='1Vqc4'>

                2. <i id='1Vqc4'><tr id='1Vqc4'><dt id='1Vqc4'><q id='1Vqc4'><span id='1Vqc4'><b id='1Vqc4'><form id='1Vqc4'><ins id='1Vqc4'></ins><ul id='1Vqc4'></ul><sub id='1Vqc4'></sub></form><legend id='1Vqc4'></legend><bdo id='1Vqc4'><pre id='1Vqc4'><center id='1Vqc4'></center></pre></bdo></b><th id='1Vqc4'></th></span></q></dt></tr></i><div id='1Vqc4'><tfoot id='1Vqc4'></tfoot><dl id='1Vqc4'><fieldset id='1Vqc4'></fieldset></dl></div>
                3. <tfoot id='1Vqc4'></tfoot>
                  本文介绍了如何从线程更新 Kivy 元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我有一个套接字客户端,它每次收到消息时都会调用 View() 类.我已经以这样一种方式拆分了我的代码,这样这个类就可以简单地使用 print() 或我喜欢的任何其他显示方法.然而,Kivy 似乎并不喜欢这种方法.我为我的视图扩展了 Kivy 的 BoxLayout 类,并且可以调用 message() 函数.这个类看起来像这样:

                  I have a socket client that calls a View() class every time it receives a message. I've split my code in such a way such that this class can simply use print() or any other display method, as I like. However, it seems that Kivy is not fond of this method. I've extended Kivy's BoxLayout class for my view and can call the message() function. The class looks something like this:

                  class View(BoxLayout):
                      def __init__(self, **kwargs):
                          super(View, self).__init__(**kwargs)
                          self.btn = Button(text='Default')
                          # Bind button press method
                          self.btn.bind(on_press=self.message)
                          self.add_widget(self.btn)
                      def message(self, message):
                          self.btn.text = 'Meow'
                          self.add_widget(Button(text='Meow'))
                          print(str(message))
                  

                  message 函数确实被调用并打印但界面没有更新.但是,当我按下按钮时,它会更新界面和打印.

                  The message function is indeed called and it prints but the interface does not update. When I press the button however, it does update the interface as well as print.

                  我研究过使用 StringProperty 来修改按钮文本,但也失败了.顺便说一句,如果我正在做的事情完全不可行,我会尝试稍后以板的形式绘制一个由 width * height 按钮组成的整个界面.

                  I've looked into using a StringProperty to modify the button text but have failed that too. Just as a note, in case what I'm doing is completely infeasible, I'm trying to later draw an entire interface consisting of width * height buttons, in the form of a board.

                  非常感谢任何意见,这让我发疯了.

                  Any input is very much appreciated, it's been driving me insane.


                  编辑 1*我关注了一些评论并尝试了一些事情.我添加了一个 Clock 类并让它从 View 安排一个 update() 方法.update 方法只是改变一些元素的文本.当我安排它时,我注意到它可以工作,如下所示:


                  EDIT 1* I've followed on a few comments and tried a few things out. I've added a Clock class and have it schedule an update() method from View. The update method simply changes the text of a few elements. I've noticed it works when I schedule it to, as shown below:

                  def update(self, *args, **kwargs):
                      self.btn.text = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for i in range(32))
                  def message(self, message):
                      try:
                          print(message)
                          self.text = 'sending'
                      except Exception as e:
                          print(e)
                  

                  线程现在只分配文本属性,如 message() 所示.周期性触发的 update() 方法也可以工作,分配随机文本.但是现在的问题是它无法设置文本.这不起作用:

                  The thread now simply assigns the text property as seen in message(). The periodically triggered update() methods works too, assigning random text. Now the issue however that it cannot set the text. This does not work:

                  def update(self, *args, **kwargs):
                      self.btn.text = self.text
                  

                  我肯定在其他地方做错了,有什么建议吗?

                  I must be doing wrong elsewhere, any suggestions?


                  编辑 2*我要调试的错误是 here.

                  推荐答案

                  由于您没有发布完整的工作示例,我只能猜测您在做什么.似乎您在线程上有一个事件(传入消息),并且您希望在发生这种情况时显示一些文本.您需要将 UI 更新推送"到主线程,但您不需要使用 Clock 进行 周期性 更新,您可以使用 Clock.schedule_once.

                  Since you don't post a full working example, I can only guess at what your doing. It seems you have an event (incoming message) on a thread, and you want to display some text when this occurs. You need to 'push' UI updates to the main thread, but you don't need to do periodic updates with Clock, you can just schedule one-time calls with Clock.schedule_once.

                  from functools import partial
                  
                  def update(self, text, *a):
                      self.btn.text = text
                  
                  def message(self, message):
                      Clock.schedule_once(partial(self.update, message), 0)
                  

                  如上所述,您可以使用 @mainthread 装饰器:

                  As inclement mentioned, you can do this 'push to main thread' automatically with the @mainthread decorator:

                  @mainthread
                  def update(self, text):
                      self.btn.text = text
                  
                  def message(self, message):
                      update(message)
                  

                  这样,每当你调用 update 时,它都会在主线程上执行.

                  This way, whenever you call update it will be executed on the main thread.

                  这篇关于如何从线程更新 Kivy 元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Kivy 1.9.0 Windows package KeyError: #39;rthooks#39;(Kivy 1.9.0 Windows 包 KeyError: rthooks)
                  Python Kivy: how to call a function on button click?(Python Kivy:如何在按钮单击时调用函数?)
                  How to disable a widget in Kivy?(如何禁用 Kivy 中的小部件?)
                  Centering an object in Kivy(在 Kivy 中将对象居中)
                  How to downgrade to Python 3.4 from 3.5(如何从 Python 3.5 降级到 Python 3.4)
                  Change button or label text color in kivy(在kivy中更改按钮或标签文本颜色)
                  <tfoot id='UIOBI'></tfoot>
                    <bdo id='UIOBI'></bdo><ul id='UIOBI'></ul>

                      • <small id='UIOBI'></small><noframes id='UIOBI'>

                          1. <legend id='UIOBI'><style id='UIOBI'><dir id='UIOBI'><q id='UIOBI'></q></dir></style></legend>
                              <tbody id='UIOBI'></tbody>
                            <i id='UIOBI'><tr id='UIOBI'><dt id='UIOBI'><q id='UIOBI'><span id='UIOBI'><b id='UIOBI'><form id='UIOBI'><ins id='UIOBI'></ins><ul id='UIOBI'></ul><sub id='UIOBI'></sub></form><legend id='UIOBI'></legend><bdo id='UIOBI'><pre id='UIOBI'><center id='UIOBI'></center></pre></bdo></b><th id='UIOBI'></th></span></q></dt></tr></i><div id='UIOBI'><tfoot id='UIOBI'></tfoot><dl id='UIOBI'><fieldset id='UIOBI'></fieldset></dl></div>