게시하기 전에 스택에 대한 제안 사항 중 몇 가지를 검색하여 적용했습니다. 아무도 일한 적이 없지만 아래 코드는 내가 일하는 가장 가까운 곳입니다.python 2.7에서 tkinter 프로젝트의 자체 업데이트가 영원히 반복됩니까?
내가 달성하고자하는 것은 여러 서버의 CPU, 프로세스 (현재 명령은 ls
임) 및 CRON 상태를 모니터하는 작은 GUI를 빌드하는 것입니다. 응용 프로그램이 자동으로 업데이트되는 기능을 제외한 모든 기능이 정상적으로 작동합니다. 이미 업데이트 버튼이 있으며 버튼을 매분마다 연결하는 기능을 refresh()
호출 할 수 있기를 원합니다.
필자는 tkinter를 처음 사용하고 프로그램에 작성한 다른 사례에 대해 약간의 의문을 가지고 있습니다. 놀라는 것이 있으시면 언제든지 말씀해주십시오.
현재 오류는 발생하지 않지만 계획된 지연없이 프로그램이 영원히 반복됩니다.
미리 감사드립니다.
#!/usr/bin/python
import ttk, os, subprocess, datetime
import ConfigParser
from Tkinter import *
config = ConfigParser.ConfigParser()
config.read("p_watch.ini")
def main():
root = Tk()
root.title('Processor Watch')
root.geometry('800x480')
app = ProcessorWatch(root)
root.mainloop()
root.destroy()
def ConfigSectionMap(section):
config_dict = {}
options = config.options(section)
for option in options:
try:
config_dict[option] = config.get(section, option)
if config_dict[option] == -1:
DebugPrint("skip: %s" % option)
except:
print("exception on %s!" % option)
config_dict[option] = None
return config_dict
class ProcessorWatch:
def __init__(self, master):
### create tabs for different machines
notebook = ttk.Notebook(master)
notebook.pack(side='top', fill=BOTH, expand=True)
frame1 = ttk.Frame(notebook)
frame1.pack(fill=BOTH, expand=True)
frame2 = ttk.Frame(notebook)
frame2.pack(fill=BOTH, expand=True)
frame3 = ttk.Frame(notebook)
frame3.pack(fill=BOTH, expand=True)
notebook.add(frame1, text='Processor1')
notebook.add(frame2, text='Processor2')
notebook.add(frame3, text='Processor3')
notebook.grid(sticky = 'NSEW')
frame1_creds = ConfigSectionMap('processor 1')
frame2_creds = ConfigSectionMap('processor 2')
frame3_creds = ConfigSectionMap('processor 3')
frame1.host_string = frame1_creds['user'] + '@' + frame1_creds['host']
frame1.index = 0
frame2.host_string = frame2_creds['user'] + '@' + frame1_creds['host']
frame2.index = 1
frame3.host_string = frame3_creds['user'] + '@' + frame1_creds['host']
frame3.index = 2
frames = [frame1,frame2,frame3]
self.cron_button = {}
self.spinbox = {}
self.refresh_num = {}
self.cpu_usage = {}
self.cpu_label = {}
self.usage_label = {}
self.quit_button = {}
self.refresh_button = {}
for frame in frames:
master.grid_columnconfigure(0, weight=1)
master.grid_rowconfigure(0, weight=1)
process_count = 0
### execute terminal commands
self.cpu_usage[frame.index] = os.popen(
"ssh -t " + frame.host_string + " grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage \"%\"}'"
).read()
grep_results = os.popen("ls")
cron_activity = os.popen("ssh -t " + frame.host_string + " \'service cron status | grep Active\'").read()
### determine and display CRON activity
if 'inactive (dead)' in cron_activity:
self.cron_button[frame.index] = Button(frame, text='CRON (inactive)',fg='white',bg='red', command= lambda f=frame: self.start_cron(master,f))
self.cron_button[frame.index].grid(padx=20, ipady=15, pady=3,row=0, column=0, sticky='EW')
else :
self.cron_button[frame.index] = Button(frame, text='CRON (active)',fg='white',bg='green', command= lambda f=frame: self.stop_cron(master,f))
self.cron_button[frame.index].grid(padx=20, ipady=15, pady=3,row=0, column=0, sticky='EW')
### config and display CPU usage
self.usage_label[frame.index] = Label(frame, text='CPU Usage \n' + str(self.cpu_usage[frame.index].rstrip()),fg='white',bg='red')
self.usage_label[frame.index].grid(padx=20, ipady=10, pady=3,row=3, column=0, sticky='EW')
### set up buttons
self.quit_button[frame.index] = Button(frame, text="QUIT", fg="red", command=frame.quit)
self.quit_button[frame.index].grid(padx=120, pady=60,row=6, column=0)
self.refresh_button[frame.index] = Button(frame, text="REFRESH", fg="blue", command= lambda f=frame: self.refresh(master,f))
self.refresh_button[frame.index].grid(padx=20, pady=3,row=5, column=0, sticky='EW')
### populate listbox
self.listbox = Listbox(frame, height=28, width=60)
self.scrollbar = ttk.Scrollbar(frame, orient=VERTICAL, command=self.listbox.yview)
self.listbox['yscrollcommand'] = self.scrollbar.set
for line in grep_results:
self.listbox.insert('end', str(line).rstrip())
process_count+=1
self.scrollbar.grid(row = 0, column = 4, sticky='NSE', rowspan=8)
self.listbox.grid(row = 0, column = 2, columnspan = 2, sticky='E', rowspan=8)
### config and display number of processes running
self.count_label = Label(frame, text='Perl Processes \n' + str(process_count),fg='black',bg='grey').grid(padx=20, ipady=10, pady=3,row=1, column=0, sticky='EW')
self.refresh_label = Label(frame, text='Last Refresh at ' + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') ,fg='black').grid(padx=0, ipady=0, pady=0,row=7, column=0, sticky='EW')
self.update(master,frame)
def refresh(self,master,frame):
# if self.usage_label[frame.index] is not None:
# self.usage_label[frame.index].destroy()
### execute terminal commands
self.cpu_usage[frame.index] = os.popen(
"ssh -t " + frame.host_string + " grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage \"%\"}'"
).read()
self.usage_label[frame.index].configure(text='CPU Usage \n' + str(self.cpu_usage[frame.index].rstrip()))
grep_results = os.popen("ls")
# grep_results = os.popen("ps aux | grep \"\.pl\" | grep -invertmatch grep")
cron_activity = os.popen("ssh -t " + frame.host_string + " \'service cron status | grep Active\'").read()
process_count = 0
self.listbox.delete(0, END)
# for line in grep_results:
# print line
# self.listbox.insert('end', str(line).rstrip())
# process_count+=1
# self.listbox.grid(row = 0, column = 2, columnspan = 2, sticky='E', rowspan=8)
self.count_label = Label(frame, text='Perl Processes \n' + str(process_count),fg='black',bg='grey').grid(padx=20, ipady=10, pady=3,row=1, column=0, sticky='EW')
self.refresh_label = Label(frame, text='Last Refresh at ' + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') ,fg='black').grid(padx=0, ipady=0, pady=0,row=7, column=0, sticky='EW')
# starting and stopping cron requires a password unless the user is configured not to
def start_cron(self,master,frame):
print "Starting Cron On " + frame.host_string
try:
os.system("ssh -t " + frame.host_string + " \'sudo service cron start\'")
print "Cron Successfully Started On " + frame.host_string
cron_activity = os.popen("ssh -t " + frame.host_string + " \'service cron status | grep Active\'").read()
if 'active (running)' in cron_activity:
self.cron_button[frame.index].configure(text='CRON (active)')
self.cron_button[frame.index].configure(bg='green')
self.cron_button[frame.index].configure(command= lambda: self.stop_cron(master,frame))
master.update()
except:
print "Cron Failed On " + frame.host_string
# starting and stopping cron requires a password unless the user is configured not to
def stop_cron(self,master,frame):
print "Stopping Cron On " + frame.host_string
try:
os.system("ssh -t " + frame.host_string + " \'sudo service cron stop\'")
print "Cron Successfully Stopped On " + frame.host_string
cron_activity = os.popen("ssh -t " + frame.host_string + " \'service cron status | grep Active\'").read()
if 'inactive (dead)' in cron_activity:
self.cron_button[frame.index].configure(text='CRON (inactive)')
self.cron_button[frame.index].configure(bg='red')
self.cron_button[frame.index].configure(command= lambda: self.start_cron(master,frame))
master.update()
except:
print "Cron Failed On " + frame.host_string
def update(self,master,frame):
# While the pipe has data, read and update the StringVar
self.refresh(master,frame)
# set the update method to run again in 1 seconds time
master.after(60000,self.update(master,frame))
if __name__ == "__main__":
main()
감사합니다. @ bryan-oakley. 이것은 확실히 나에게 무언가를 가르치고 googleing과 시행 착오의 또 다른 라운드를 촉발시켰다. 나는 뭔가를 올바르게 이해하지 못한다면 전체 프로그램에 근본적으로 잘못된 것이있을 것이라고 생각합니다. 귀하의 예제에서와 같이 루트 (또는 자기 자신의 경우)를 사용하려고하면 오류'AttributeError : ProcessorWatch 인스턴스에 'after'' 속성이 없습니다. 그러나'self.update()'대신'master.update()'를 실행하려고하면 에러가 없지만'update()'는 호출되지 않습니다. ProcessorWatch를 잘못 초기화합니까? –
@ThomasCannon'after'는 모든 위젯에서 사용할 수있는 방법입니다. 내 예제에서는 단순히 _any_ widget을 전달해야합니다. 귀하의 경우 '자기'는 위젯이 아니므로 오류입니다. –
아! 그것은 많은 것을 명확히합니다. 고맙습니다! –