2015-11-19 88 views
9

我有一个套接字客户端,每次接收到消息时都会调用View()类。我已经按照这样的方式分割我的代码,以便这个类可以简单地使用print()或任何其他显示方法,如我所愿。但是,基维似乎并不喜欢这种方法。我为我的观点扩展了Kivy的BoxLayout类,并且可以调用message()函数。该类看起来是这样的:如何从线程更新Kivy元素?

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)) 

消息函数确实被调用,它会打印,但接口不会更新。然而,当我按下按钮时,它会更新界面以及打印。

我已经研究过使用StringProperty修改按钮文本,但也失败了。就像一张纸条一样,万一我所做的事情是完全不可行的,我想以后会以板子的形式绘制一个由width * height按钮组成的整个界面。

任何输入是非常赞赏,它一直让我疯狂。


编辑1 * 我跟随了几条评论,并尝试了几件事。我已经添加了 Clock课程,并安排了 Viewupdate()方法。更新方法只是简单地改变几个元素的文本。我注意到它的工作原理,当我安排其,如下图所示:

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() text属性。周期性触发的update()方法也可以工作,分配随机文本。现在的问题是,它无法设置文本。这是行不通的:

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

我一定在别处做错了,有什么建议吗?


EDIT 2 * 我试图调试的错误是 here

+0

您不能修改主线程以外的线程的UI元素或属性。查看Kivy'''Clock'''类来调度函数以在mainthread上运行。 – bj0

+0

除了@ bj0的回答,您可以使用'@ mainthread'装饰器将此方法自动应用于函数。 – inclement

+0

嘿,我已经编辑了这篇文章进一步的调查结果。我很感激帮助,并且使用'Clock()'的建议,但是如上所述,它仍然不完全正常工作。 – timur

回答

3

既然你没有发布一个完整的工作示例,我只能猜测你在做什么。看起来你在一个线程上有一个事件(传入消息),并且当发生这种情况时你想显示一些文本。您需要将UI更新“推送”至主线程,但您不需要执行定期更新,您可以使用Clock.schedule_once安排一次性调用Clock

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装饰做“推到主线程”:

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

def message(self, message): 
    update(message) 

这样一来,只要您拨打update它会在主线程上执行。

+0

我的意图是不发布完整的工作示例,因为这是作业的一部分,我不想让我的作品被抄袭。我已经在GitHub上公布了回购,可以在这里找到(https://github.com/TimurKiyivinski/falampous-coconut-appreciator)。自从我删除了时钟方法并重新使用'@ mainthread'。你正在寻找的文件是'client.py'。 – timur

+0

通常,当您不想(或不能)发布您正在使用的代码时,只需创建一个具有您尝试解决的问题的最简单的裸机应用程序。它有助于人们重现您的问题。 – bj0

+2

好吧,在浏览你的代码后,它看起来不像Kivy问题,而是一个'''multiprocessing'''问题。单独的进程不共享内存,因此很多对象之间的引用无法正常工作。使用线程代替,它应该按照您的思维方式工作 – bj0