【问题标题】:Python GUI and animationPython GUI 和动画
【发布时间】:2016-11-16 05:49:27
【问题描述】:

我正在创建一个 GUI,以使用 tkinter 绘制来自温度传感器的实时图表,以及来自 matplotlib 的动画功能。我得到了漂亮的实时图表。但我面临的问题是,实时图表在我运行应用程序后立即开始。我已经创建了一个按钮来调用 class StartPage 中的命令,但它不起作用。我希望我的应用程序在单击 StartPage 类中的 Start Monitoring 时开始收集数据和绘制图表

如果有人能帮我解决这个问题,那就太好了。

比你。

def animate(i):

ipcon = IPConnection() # Create IP connection
ptc1 = BrickletPTC(UID1, ipcon) # S3 
ptc2 = BrickletPTC(UID2, ipcon) # S7
ptc3 = BrickletPTC(UID3, ipcon) # S7
ptc4 = BrickletPTC(UID4, ipcon) # S7

ipcon.connect(HOST, PORT) # Connect to brickd
temperature1 = ptc1.get_temperature() - 20
temperature2 = ptc2.get_temperature() + 6
temperature3 = ptc3.get_temperature() + 3
temperature4 = ptc4.get_temperature() + 29

l = [temperature1, temperature2]
avgTemp = np.mean(l)
avgTempM = str(avgTemp/100)

dataArrayavg = avgTempM.split(',')
tempavg = float(dataArrayavg[0])
tempCavg.append(tempavg)
avg.set_xlabel('Time [s]', fontsize = 10)
avg.set_ylabel('Temperature [°C]', fontsize = 10)
y_formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
avg.yaxis.set_major_formatter(y_formatter)
titleavg = "Average Room Temperature: " + str(temperature1/100) + " °C"
avg.set_title(titleavg, fontsize = 12)
avg.plot(tempCavg, "#483D8B")


f1.savefig('RoomTemperature.png')
f2.savefig('ObjectTemperature.png')


class StartPage(tk.Frame):


def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)

    # Adding a logo to the startpage
    logo = Image.open("Gemeinschaftslogo(5).jpg")
    Image1 = ImageTk.PhotoImage(logo)

    # defining the image label
    imageLabel = Label(self, image = Image1)
    imageLabel.image = Image1
    imageLabel.pack(pady=30, padx=30)

    #defining labels
    label = ttk.Label(self, text="Zustandsüberwachung (Condition Monitoring) von industriellen Computertomographie-Systemen", font = LARGE_FONT,)
    label.pack(pady=10, padx=10)

    #creating button
    #if agree then move to temperature graph
    button1 = ttk.Button(self, text="Start Monitoring", 
                        command=lambda: animate())  # with lambda we are moving from start page to page 1

    button1.pack(pady=30, padx=30)

    button2 = ttk.Button(self, text="Enter", 
                        command=lambda: controller.show_frame(RoomTempGraph))  # with lambda we are moving from start page to page 1

ani1 = animation.FuncAnimation(f1,animate, interval = 1000)
app.mainloop()

【问题讨论】:

  • 您的缩进显示已损坏。不清楚def animate(i):里面有多少代码
  • @BryanOakley 感谢您的回复,可能在复制文本时出错。 animate(i) 里面的缩进很好。
  • 我想这是触发动画的那一行:ani1 = animation.FuncAnimation(f1,animate, interval = 1000)。那应该在按钮命令中移动。而在 button1 命令中,您的 lambda:animate() 似乎错过了 i 参数。
  • @Jean-FrançoisFabre 我几乎尝试了所有方法。是的 (i) 也不返回任何东西。我尝试将整个命令移动到按钮命令中,但没有运气.. 有什么方法可以在按钮命令中移动 'ani1 = animation.FuncAnimation(f1,animate, interval = 1000)' 以便它开始打印图形只有当它被要求时..?

标签: python user-interface animation matplotlib tkinter


【解决方案1】:

好的,肮脏的黑客:

global do_animate
do_animate = False

如下更改你的命令:

#creating button
#if agree then move to temperature graph
button1 = ttk.Button(self, text="Start Monitoring", 
                    command=lambda: do_animate=True)  # with lambda we are moving from start page to page 1

animate 中返回if do_animate == False

【讨论】:

  • 感谢您的努力 Jean 我试过了,但是当 'ani1 = animation.FuncAnimation(f1,animate, interval = 1000)' 命令从那里移动时,它不显示图表。跨度>
  • 改变了解决方案
  • 很遗憾没有输出。感谢您的努力和帮助 Jean 似乎这个动画功能很痛苦,我应该尝试做一些简单的事情。 :D
  • 也许我对全局变量的东西做错了。我讨厌全局变量。
【解决方案2】:

刚刚找到了解决我自己问题的方法。我希望它可以帮助某人

在 app.mainloop() 之前我创建了一个测试函数

app.geometry("1280x720")


def test():

   ani1 = animation.FuncAnimation(f1,animate1, interval = 1000)
   ani2 = animation.FuncAnimation(f2,animate2, interval = 1000)
   ani1._start(test)
   ani2._start(test)

app.mainloop()

我在页面中传递给我的命令按钮

button1 = ttk.Button(self, text="Start Monitoring", 
                        command=lambda: test())  # with lambda we are moving from start page to page 1

我不知道它是如何工作的,但是当我要求它时它开始绘图.. :D

再次感谢大家。 祝你有美好的一天

【讨论】:

    【解决方案3】:

    类似于 Jean-François Fabre 的解决方案,这不会阻止您的 animate() 运行,但会阻止它执行任何操作。

    def animate(i):
       global draw
       if draw:
          """ here goes all you want your animate func to do """
       draw = False
    

    因此,通过在 if draw 中添加您想要执行的操作,您将确保它只会被绘制一次,然后不会再次被绘制。如果您希望它继续被绘制,请在最后删除 draw = False。根据您的需要,您需要在 init 中设置 draw。

    class startpage(tk.Frame):
       def __init__(self, parent, controller):
          global draw
          draw = False #if you want it to start without drawing
    

    这至少是我如何让这种事情在我的程序中发挥作用。您显然需要一种方法在某处将 draw 设置为 true,这可能是任何事情。在我的程序中,我将其设置为在更改要绘制的内容时绘制,但您可能需要一个按钮,因为您希望它继续运行。

    【讨论】:

    • 您好@Paolo 感谢您的回复.. 我正在使用您所说的内容,但它在动画中显示错误,说未定义绘图.. 对不起,我是一个邻居,我没有理解'def def __init__(self, parent, controller):' 中的 'draw=False' 做了什么。我认为它会抛出错误,因为那里没有定义 draw..
    • 抱歉响应缓慢!所以 init 将在您启动程序时第一次运行。因此,其中声明的任何全局变量都将被“保存”。问题是我没有说它应该是全球性的。我编辑修复它。目的是让程序知道存在一个无论如何都应该可以访问的变量,并且该变量的值是 False。当你的程序进入动画时,它会检查:是 Draw True 吗?它会知道 draw 是 False,并且不会在 if 语句中做任何事情。然后,您需要一个按钮将 draw 设置为 True,以便在您单击时进行绘制。
    猜你喜欢
    • 2021-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多