1#! /usr/bin/env python
2# Tkinter interface to Linux `kill' command.
3
4from Tkinter import *
5from string import splitfields
6from string import split
7import commands
8import os
9
10class BarButton(Menubutton):
11    def __init__(self, master=None, **cnf):
12        apply(Menubutton.__init__, (self, master), cnf)
13        self.pack(side=LEFT)
14        self.menu = Menu(self, name='menu')
15        self['menu'] = self.menu
16
17class Kill(Frame):
18    # List of (name, option, pid_column)
19    format_list = [('Default', '', 0),
20                   ('Long', '-l', 2),
21                   ('User', '-u', 1),
22                   ('Jobs', '-j', 1),
23                   ('Signal', '-s', 1),
24                   ('Memory', '-m', 0),
25                   ('VM', '-v', 0),
26                   ('Hex', '-X', 0)]
27    def kill(self, selected):
28        c = self.format_list[self.format.get()][2]
29        pid = split(selected)[c]
30        os.system('kill -9 ' + pid)
31        self.do_update()
32    def do_update(self):
33        name, option, column = self.format_list[self.format.get()]
34        s = commands.getoutput('ps -w ' + option)
35        list = splitfields(s, '\n')
36        self.header.set(list[0])
37        del list[0]
38        y = self.frame.vscroll.get()[0]
39        self.frame.list.delete(0, AtEnd())
40        for line in list:
41            self.frame.list.insert(0, line)
42        self.frame.list.yview(int(y))
43    def do_motion(self, e):
44        e.widget.select_clear(0, END)
45        e.widget.select_set(e.widget.nearest(e.y))
46    def do_leave(self, e):
47        e.widget.select_clear(0, END)
48    def do_1(self, e):
49        self.kill(e.widget.get(e.widget.nearest(e.y)))
50    def __init__(self, master=None, **cnf):
51        Frame.__init__(self, master, cnf)
52        self.pack(expand=1, fill=BOTH)
53        self.bar = Frame(self, name='bar', relief=RAISED,
54                         borderwidth=2)
55        self.bar.pack(fill=X)
56        self.bar.file = BarButton(self.bar, text='File')
57        self.bar.file.menu.add_command(
58                label='Quit', command=self.quit)
59        self.bar.view = BarButton(self.bar, text='View')
60        self.format = IntVar(self)
61        self.format.set(2)
62        for num in range(len(self.format_list)):
63            self.bar.view.menu.add_radiobutton(
64                    label=self.format_list[num][0],
65                    command=self.do_update,
66                    variable=self.format,
67                    value=num)
68        #self.bar.view.menu.add_separator()
69        #XXX ...
70        self.bar.tk_menuBar(self.bar.file, self.bar.view)
71        self.frame = Frame(self, relief=RAISED, borderwidth=2)
72        self.frame.pack(expand=1, fill=BOTH)
73        self.header = StringVar(self)
74        self.frame.label = Label(self.frame, relief=FLAT, anchor=NW,
75                                 borderwidth=0,
76                                 textvariable=self.header)
77        self.frame.label.pack(fill=X)
78        self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL)
79        self.frame.list = Listbox(self.frame, relief=SUNKEN,
80                                  selectbackground='#eed5b7',
81                                  selectborderwidth=0,
82                                  yscroll=self.frame.vscroll.set)
83        self.frame.vscroll['command'] = self.frame.list.yview
84        self.frame.vscroll.pack(side=RIGHT, fill=Y)
85        self.frame.list.pack(expand=1, fill=BOTH)
86        self.update = Button(self, text="Update",
87                             command=self.do_update)
88        self.update.pack(expand=1, fill=X)
89        self.frame.list.bind('<Motion>', self.do_motion)
90        self.frame.list.bind('<Leave>', self.do_leave)
91        self.frame.list.bind('<1>', self.do_1)
92        self.do_update()
93
94if __name__ == '__main__':
95    kill = Kill(None, borderwidth=5)
96    kill.winfo_toplevel().title('Tkinter Process Killer')
97    kill.winfo_toplevel().minsize(1, 1)
98    kill.mainloop()
99