| #! /usr/bin/env python | |
| # Tkinter interface to Linux `kill' command. | |
| from Tkinter import * | |
| from string import splitfields | |
| from string import split | |
| import commands | |
| import os | |
| class BarButton(Menubutton): | |
| def __init__(self, master=None, **cnf): | |
| apply(Menubutton.__init__, (self, master), cnf) | |
| self.pack(side=LEFT) | |
| self.menu = Menu(self, name='menu') | |
| self['menu'] = self.menu | |
| class Kill(Frame): | |
| # List of (name, option, pid_column) | |
| format_list = [('Default', '', 0), | |
| ('Long', '-l', 2), | |
| ('User', '-u', 1), | |
| ('Jobs', '-j', 1), | |
| ('Signal', '-s', 1), | |
| ('Memory', '-m', 0), | |
| ('VM', '-v', 0), | |
| ('Hex', '-X', 0)] | |
| def kill(self, selected): | |
| c = self.format_list[self.format.get()][2] | |
| pid = split(selected)[c] | |
| os.system('kill -9 ' + pid) | |
| self.do_update() | |
| def do_update(self): | |
| name, option, column = self.format_list[self.format.get()] | |
| s = commands.getoutput('ps -w ' + option) | |
| list = splitfields(s, '\n') | |
| self.header.set(list[0]) | |
| del list[0] | |
| y = self.frame.vscroll.get()[0] | |
| self.frame.list.delete(0, AtEnd()) | |
| for line in list: | |
| self.frame.list.insert(0, line) | |
| self.frame.list.yview(int(y)) | |
| def do_motion(self, e): | |
| e.widget.select_clear(0, END) | |
| e.widget.select_set(e.widget.nearest(e.y)) | |
| def do_leave(self, e): | |
| e.widget.select_clear(0, END) | |
| def do_1(self, e): | |
| self.kill(e.widget.get(e.widget.nearest(e.y))) | |
| def __init__(self, master=None, **cnf): | |
| Frame.__init__(self, master, cnf) | |
| self.pack(expand=1, fill=BOTH) | |
| self.bar = Frame(self, name='bar', relief=RAISED, | |
| borderwidth=2) | |
| self.bar.pack(fill=X) | |
| self.bar.file = BarButton(self.bar, text='File') | |
| self.bar.file.menu.add_command( | |
| label='Quit', command=self.quit) | |
| self.bar.view = BarButton(self.bar, text='View') | |
| self.format = IntVar(self) | |
| self.format.set(2) | |
| for num in range(len(self.format_list)): | |
| self.bar.view.menu.add_radiobutton( | |
| label=self.format_list[num][0], | |
| command=self.do_update, | |
| variable=self.format, | |
| value=num) | |
| #self.bar.view.menu.add_separator() | |
| #XXX ... | |
| self.bar.tk_menuBar(self.bar.file, self.bar.view) | |
| self.frame = Frame(self, relief=RAISED, borderwidth=2) | |
| self.frame.pack(expand=1, fill=BOTH) | |
| self.header = StringVar(self) | |
| self.frame.label = Label(self.frame, relief=FLAT, anchor=NW, | |
| borderwidth=0, | |
| textvariable=self.header) | |
| self.frame.label.pack(fill=X) | |
| self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL) | |
| self.frame.list = Listbox(self.frame, relief=SUNKEN, | |
| selectbackground='#eed5b7', | |
| selectborderwidth=0, | |
| yscroll=self.frame.vscroll.set) | |
| self.frame.vscroll['command'] = self.frame.list.yview | |
| self.frame.vscroll.pack(side=RIGHT, fill=Y) | |
| self.frame.list.pack(expand=1, fill=BOTH) | |
| self.update = Button(self, text="Update", | |
| command=self.do_update) | |
| self.update.pack(expand=1, fill=X) | |
| self.frame.list.bind('<Motion>', self.do_motion) | |
| self.frame.list.bind('<Leave>', self.do_leave) | |
| self.frame.list.bind('<1>', self.do_1) | |
| self.do_update() | |
| if __name__ == '__main__': | |
| kill = Kill(None, borderwidth=5) | |
| kill.winfo_toplevel().title('Tkinter Process Killer') | |
| kill.winfo_toplevel().minsize(1, 1) | |
| kill.mainloop() |