python - Run motor till stop button is pressed but have the ability to switch between windows -


i wish make motor control app. have 3 windows, follows (unfortunately cannot upload pictures yet, can upload them other way ):

so, want when user clicks "go" button motor rotates , when user clicks "stop" button motor stops. after "go" button has been pressed go different window such window in top , bottom picture.

however, gui freezes after clicking "go" button. there way doesn't freeze gui , allow me desired functionality?

#! usr/bin/env python  import threading import serial import time import tkinter tk     system_state_is_run=false class dh_corp_scada2(tk.tk):     def __init__(self, *args,**kwargs):               tk.tk.__init__(self, *args, *kwargs)               container=tk.frame(self)               container.pack(side="top",fill="both",expand=true)               container.grid_rowconfigure(0,weight=10)               container.grid_columnconfigure(0,weight=10)               self.frames={}               f in (homepage, controlpage, speed1page):               frame=f(container,self)               self.frames[f]=frame               frame.grid(row=0, column=0, sticky="nsew")                self.show_frame(homepage)      def show_frame(self,cont):         frame=self.frames[cont]         frame.tkraise()  class homepage(tk.frame):       def __init__(self, parent, controller):          tk.frame.__init__(self, parent)          somelabel=tk.label(self,text='welcome agc scada....')          agc_control=tk.button(self,text='agc control & parameters',               command=lambda:controller.show_frame(controlpage))          agc_speed=tk.button(self,text='monitor speed',command=lambda:                                controller.show_frame(speed1page))          exit_button=tk.button(self, text='exit',command=close_window)              somelabel.grid(row=0, sticky="w")          agc_control.grid(row=2, column=1, sticky="ew",padx=2,pady=2)          agc_speed.grid(row=3,column=1, sticky="ew", padx=2,pady=2)          exit_button.grid(row=4,column=1, sticky="ew",padx=2,pady=2)       class controlpage(tk.frame):           def __init__(self, parent, controller):           tk.frame.__init__(self, parent)           somelabel1=tk.label(self,text='from page may change p.')           go_home1=tk.button(self,text='home page',command=lambda:controller.show_frame(homepage))           agc_speed=tk.button(self,text='monitor speed',command=lambda:controller.show_frame(speed1page))           exit_button=tk.button(self, text='exit',command=close_window)           go_button=tk.button(self,text='go',command=system_state_is_runxy1)           stop_button=tk.button(self,text='stop', command=system_state_is_runxy2)            somelabel1.grid(row=0, sticky="w")           go_button.grid(row=2,column=1, sticky="ew",padx=2,pady=2)           stop_button.grid(row=3,column=1, sticky="ew",padx=2,pady=2)           go_home1.grid(row=4, column=1, sticky="ew",padx=2,pady=2)           agc_speed.grid(row=5,column=1, sticky="ew", padx=2,pady=2)           exit_button.grid(row=6,column=1, sticky="ew",padx=2,pady=2)        class speed1page(tk.frame):          def __init__(self, parent, controller):          tk.frame.__init__(self, parent)          somelabel2=tk.label(self,text='from page can monitor speed parameter in channel 1 or left motor.')          go_home2=tk.button(self,text='home  page',command=lambda                             :controller.show_frame(homepage))          agc_control=tk.button(self,text='agc control & parameters',command=                             lambda:controller.show_frame(controlpage))          exit_button=tk.button(self, text='exit',command=close_window)          somelabel2.grid(row=0, sticky="w")          go_home2.grid(row=2,column=1, sticky="ew", padx=2,pady=2)          agc_control.grid(row=3, column=1, sticky="ew",padx=2,pady=2)          exit_button.grid(row=4,column=1, sticky="ew",padx=2,pady=2)            def system_state_is_runxy1():     global system_state_is_run     system_state_is_run=true     print(system_state_is_run)#check if system_state_is_run changes     running_car()  def system_state_is_runxy2():     global system_state_is_run     system_state_is_run=false     print(system_state_is_run)#check if system_state_is_run changes     running_car()  def running_car():      print(system_state_is_run)#check if system_state_is_run changes      if system_state_is_run==true:          motor_run_callback()          running_car()     else:          motor_off_callback()          return   def motor_run_callback():# set motor speed 25rpm     ser = serial.serial('com6',115200,timeout=0)     time.sleep(0.025)     ser.write(bytes('!g 1 250\r','utf-8'))     ser.close()     return  def motor_off_callback(): #set motor speed 0     ser = serial.serial('com6',115200,timeout=0)     time.sleep(0.025)     ser.write(bytes('!g 1 0\r','utf-8'))     ser.close()   def close_window():      app.destroy()   app=dh_corp_scada2()             app.mainloop() 

  • the button calls system_state_is_runxy1.
  • system_state_is_runxy1 sets system_state_is_run true, , calls running_car().
    • running_car() sees system_state_is_run true, , calls motor_run_callback(), , calls again.
    • running_car() sees system_state_is_run true, , calls motor_run_callback(), , calls again.
    • running_car() sees system_state_is_run true, , calls motor_run_callback(), , calls again.
    • ... , on

nowhere in logic allow gui process events. since tkinter single threaded, must allow event loop process events gui remain responsive.

whether visualizing or not, doing animation. animation typically done after method. call function tiny bit of work (animates motor, monitors port, etc.) , calls again in few milliseconds. in time after finished before called again, event loop has chance handle events such click on "stop" button.

for longer description see https://stackoverflow.com/a/11505034/7432


Comments

Popular posts from this blog

java - Date formats difference between yyyy-MM-dd'T'HH:mm:ss and yyyy-MM-dd'T'HH:mm:ssXXX -

c# - Get rid of xmlns attribute when adding node to existing xml -