Python:关于在GUI应用程序中实现线程的建议
我真的很难在我的应用程序中实现线程。这可能会有点长,所以请容忍我。我的问题更多的是关于我的应用程序的建议结构,而不是关于添加线程的代码 首先,让我展示我的应用程序的视觉效果。而不是解释一些事情。应用程序通过串行端口上的Arduino提供数据。在一个螺母外壳中,我打开一个串行端口,逐行读取数据,处理它,并在屏幕上直观地显示它。视觉效果分为两部分。第一个是由Arduino通过串行端口保存和传递的每个赛车手的时间。第二种方法是根据比赛的距离来计算比赛进度,这种距离以时钟样式的指针表示,您也可以在屏幕截图中看到。这一切都是实时发生的,来自Arduino的数据通过串口传输速度非常快 一旦比赛开始,这个函数就是我解析数据并告诉系统如何处理数据的方式Python:关于在GUI应用程序中实现线程的建议,python,multithreading,user-interface,Python,Multithreading,User Interface,我真的很难在我的应用程序中实现线程。这可能会有点长,所以请容忍我。我的问题更多的是关于我的应用程序的建议结构,而不是关于添加线程的代码 首先,让我展示我的应用程序的视觉效果。而不是解释一些事情。应用程序通过串行端口上的Arduino提供数据。在一个螺母外壳中,我打开一个串行端口,逐行读取数据,处理它,并在屏幕上直观地显示它。视觉效果分为两部分。第一个是由Arduino通过串行端口保存和传递的每个赛车手的时间。第二种方法是根据比赛的距离来计算比赛进度,这种距离以时钟样式的指针表示,您也可以在屏幕截
def letsrace(self):
def getsome():
global var1, var2, totalCount
self.reset()
self.senddemo()
letsRace = 1
ser.write('!g\n')
while (letsRace == 1):
#print mycount
s = ser.readline()
s = s.strip('\r\n')
#Check for :
pattern = r'[:]'
if re.search(pattern, s):
#print 'VALID : %r' % (s,)
var1, var2 = s.split(":")
self.options[var1]()
else:
#print 'INVALID : %r' % (s,)
pass
if totalCount == 4:
letsRace = 0
self.racecomplete()
thread = threading.Thread(target=getsome)
thread.start()
正如你所看到的,我确实有一个线索。这非常有效,因为显示每个赛车手的计时器会使应用程序陷入困境。在race函数中添加线程后,我就没有问题了
我还应该指出,我使用字典作为案例陈述。这是在一个比赛级别的ini上。下面看起来像这样
self.options = {"0": self.draw_r1,
"1": self.draw_r2,
"2": self.draw_r3,
"3": self.draw_r4,
"0f": self.racerFinish,
"1f": self.racerFinish,
"2f": self.racerFinish,
"3f": self.racerFinish,
"x": self.emptyLine,
"t": self.raceTime,
"G": self.letsGo,
"CD": self.countDown,
"C": self.emptyLine,
}
基于我从实时数据流解析的内容,我使用正确的函数处理它。到目前为止,我想你会同意的
我刚刚完成了添加到时钟样式显示器顶部的racer拨号盘的代码。我用枕头(PIL)来旋转刻度盘。这也是非常基本的东西。我有一个画布,我在画布上添加了四个图像来代表每个参赛者。我为每个参赛者使用不同的功能来更新他们在比赛中的位置。它们是您在上面的词典中看到的前四个函数。下面是其中一个例子。除了在时钟上更新的图像外,它们几乎都是一样的
def draw_r4(self):
if self.r4_isdone == 0:
self.angle = (float(var2) * self.movement ) * -1
if self.angle < -360:
self.angle = 0
self.canvas.delete(self.canvas_obj4)
self.newarrow4 = ImageTk.PhotoImage(self.image_r4.rotate(self.angle))
self.canvas_obj4 = self.canvas.create_image(215, 215, image=self.newarrow4)
def draw_r4(自):
如果self.r4_isdone==0:
自转角=(浮动(var2)*自移动)*-1
如果自转角<-360:
自转角=0
self.canvas.delete(self.canvas_obj4)
self.newarrow4=ImageTk.PhotoImage(self.image\u r4.旋转(self.angle))
self.canvas_obj4=self.canvas.create_image(215215,215,image=self.newarrow4)
如果您熟悉PIL和旋转图像,您就会知道它基本上会一遍遍地重新绘制图形以显示新的位置。这就是系统现在存在的问题。在Win8或Mac上,拨号不会真正影响应用程序的性能。在处理能力有限的树莓圆周率上。一场演示赛大约需要6.4秒才能完成,但在RPi上,由于图像重画的处理,大约需要15秒。为了让它像树莓一样工作,我想让每个拨号动画在自己的线程中运行
所以,如果你还在读这本伟大的书。很抱歉这么长时间。现在我的问题。您建议我如何将每个刻度盘的移动都纳入到它自己的线程中?请记住,上面的主要赛车功能有一个线程。我读过的每一个线程示例都非常基础,以至于在一个完整的gui应用程序中实现任何东西都会让我有点头晕目眩 是否在动画的每一帧中创建新图像?在绘图代码中,我没有看到在创建新对象之前删除旧对象的任何地方。我应该指出,在比赛过程中,重新绘制刻度盘位置的四个函数被称为100,甚至可能超过1000次。这将取决于比赛距离。我曾尝试将每个draw函数像race函数一样封装在一个线程中,但这显然没有帮助,因为它们在比赛过程中被调用了很多次。Bryan,尽管我的知识有限,但我认为你不必删除它。我只是觉得比尔会照顾你的。如果不是删除它们,它们不是都会出现在屏幕上吗?布莱恩,我只是看了几个例子,这个例子每次都会删除。因此,如果它在屏幕上不可见且未被删除,它在哪里?只是在内存中某个地方减慢了速度?我更新了代码,使其具有删除功能,但这不会影响拨号的速度。