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
setssystem_state_is_run
true
, , callsrunning_car()
.running_car()
seessystem_state_is_run
true
, , callsmotor_run_callback()
, , calls again.running_car()
seessystem_state_is_run
true
, , callsmotor_run_callback()
, , calls again.running_car()
seessystem_state_is_run
true
, , callsmotor_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
Post a Comment