|
1 #! /usr/bin/env python |
|
2 # Tkinter interface to Linux `kill' command. |
|
3 |
|
4 from Tkinter import * |
|
5 from string import splitfields |
|
6 from string import split |
|
7 import commands |
|
8 import os |
|
9 |
|
10 class 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 |
|
17 class 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 |
|
94 if __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() |