我有一个python应用程序,它基本上是aptitude的前端。奇怪的是,程序会产生不同的结果,具体取决于它是从GUI启动(通过.py,桌面启动器还是sym链接),还是在cli上调用它。
以下是代码和屏幕截图
#!/usr/bin/python
import gtk
import pygtk
import os
import sys
import re
import getpass
get_username = getpass.getuser()
class createUI:
####################
def on_column_clicked(self, col1, col2, col3, col4 ):
#This function allows the columns to be resorted upon click
if sort_order == gtk.SORT_ASCENDING:
sort_order = gtk.SORT_DESCENDING
else:
sort_order = gtk.SORT_ASCENDING
####################
def install_selected(self, option):
#This function determines which field has been selected
#Then it picks the package name from the second column
self.selection = treeview.get_selection()
self.selection.set_mode(gtk.SELECTION_SINGLE)
#We only want the user to be able to select one file
tree_model, tree_iter = self.selection.get_selected()
#The line below is the line which determines which column is passed to the installer
self.selected_program = tree_model.get_value(tree_iter, 1)
print self.selected_program
os.system("gksudo 'aptitude install %s -y'" % self.selected_program)
##################
def search_packages(self, clicked):
#this is the function which searches for the packages and stores the list in a file
#for easier manipulation. It starts by trying to remove any temp files in case there was not a clean shutdown
#previously
try:
os.system('rm -rf /home/%s/.tux_search/somefile' % get_username)
except:
pass
search = self.search_package.get_text()
os.system("aptitude search %s > /home/%s/.tux_search/somefile" % (search,get_username) )
if search != "":
#Call the results
self.createTable()
#destroy the search window
self.window.destroy()
else:
pass
#############
def kill_program(self, click):
#attempt to clean up before quitting
os.system('rm -rf /home/%s/.tux_search/somefile' % get_username)
gtk.main_quit()
#####################
def uninstall_program(self, click):
#this section functions in the same way as the install package except it purges files instead of installs them
self.selection = treeview.get_selection()
self.selection.set_mode(gtk.SELECTION_SINGLE)
tree_model, tree_iter = self.selection.get_selected()
self.selected_program = tree_model.get_value(tree_iter, 1)
os.system("gksudo 'aptitude --purge remove %s -y'" % self.selected_program)
####################
def __init__(self):
self.create_search(None)
##################
def create_search(self, dummy):
try:
self.aptitude_results.destroy()
except:
pass
#create the initial search window
self.window = gtk.Window()
#centre the window
self.window.set_position(gtk.WIN_POS_CENTER)
#We set the default because otherwise the dialogue box looks disproportionate
self.window.set_default_size(300,150)
self.window.set_title("Search for a Package")
#Deal with the search label. It goes inside of an Hbox for horizontal positioning
self.vbox = gtk.VBox(spacing=10)
self.search_label_hbox_1 = gtk.HBox(spacing=10)
self.label = gtk.Label("Please enter a program to search for :")
self.search_label_hbox_1.pack_start(self.label)
#Add the entry box for user input, again in an Hbox
self.search_entry_hbox_2 = gtk.HBox(spacing=10)
self.search_package = gtk.Entry()
self.search_entry_hbox_2.pack_start(self.search_package)
#add the buttons
self.buttons_hbox_3 = gtk.HBox(spacing=10)
self.button_ok = gtk.Button("Get Results!")
#the results button calls the 'search_packages' function
self.button_ok.connect("clicked", self.search_packages)
self.buttons_hbox_3.pack_start(self.button_ok)
self.button_exit = gtk.Button("Get me Outta Here!")
self.buttons_hbox_3.pack_start(self.button_exit)
self.button_exit.connect("clicked", gtk.main_quit)
#here we put the hboxes inside of the vbox (verticle box)
self.vbox.pack_start(self.search_label_hbox_1)
self.vbox.pack_start(self.search_entry_hbox_2)
self.vbox.pack_start(self.buttons_hbox_3)
#add everything to the main window and display it
self.window.add(self.vbox)
self.window.show_all()
gtk.main()
#####################3
def createTable(self):
global treeview
builder = gtk.Builder()
builder.add_from_file('/home/%s/.tux_search/aptitude_frontend.glade' % get_username)
builder.connect_signals(self)
self.aptitude_results = builder.get_object('window')
treeview = builder.get_object('treeview')
table_vbox = builder.get_object('vbox')
treestore = builder.get_object('liststore1')
cols = ["Installed?", "Package Name", "Description"]
treeview.cell = [None] * len(cols)
treeview_column = [None] * len(cols)
for column_number, col in enumerate(cols):
treeview.cell[column_number] = gtk.CellRendererText()
treeview_column[column_number] = gtk.TreeViewColumn(col, treeview.cell[column_number])
treeview_column[column_number].add_attribute(treeview.cell[column_number], 'text', column_number)
treeview_column[column_number].set_resizable(True)
treeview_column[column_number].set_reorderable(True)
treeview_column[column_number].set_sort_indicator(True)
treeview_column[column_number].set_sort_column_id(column_number)
treeview.append_column(treeview_column[column_number])
#read the output from aptitude
fetch_results = open("/home/%s/.tux_search/somefile" % get_username).readlines()
#A results list is required to get rid of all the wierd spaces that aptitude produces for terminal output
results_list = []
for single_result in fetch_results:
#turn the results into a tuple by splitting at the spaces
#this allows us to get rid of the spaces
single_result = single_result.split(" ")
counter = 0
place_holder = []
while counter < len(single_result):
#here we are checking to see if a line starts with a space/tab/new line and has nothing else
if re.match(r'^\s*$', single_result[counter]):
#we dont want to append these so instead we will just pass over them
pass
else:
place_holder.append(single_result[counter])
counter +=1
#the place holder is required so that we can turn each tuple back into a string so that it can be appended to the actual results list
place_holder = " ".join(place_holder)
#get rid of the new line characters if they exist
place_holder = place_holder.rstrip()
results_list.append(place_holder)
for column_contents in results_list:
column_contents = column_contents.split(" ")
#since the information was entered into the list in the following way "i eog - <package_description>"
#we want to put all the descriptive words into a single element so they can be placed into
#a column. We can also tell that the descriptions start at the 4th element
element = 3
package_description = []
while element < len(column_contents):
package_description.append(column_contents[element])
element +=1
package_description = " ".join(package_description)
#This section translates the
if column_contents[0] == "i":
column_contents[0] = "y"
treestore.append(
[ column_contents[0], column_contents[1], package_description ]
)
elif column_contents[0] == "v":
#skip the meta package information
pass
elif column_contents[0] == "p":
column_contents[0] = "n"
treestore.append(
[ column_contents[0], column_contents[1], package_description ]
)
#add the tool bar for 'nice' buttons
toolbar = builder.get_object('toolbar')
#quit button
quit_icon = gtk.Image()
quit_icon.set_from_file("/home/%s/.tux_search/icons/quit.png" % get_username)
quit_button = gtk.ToolButton(label="Quit!", icon_widget=quit_icon)
toolbar.insert(quit_button, 0)
quit_button.connect("clicked", self.kill_program)
#uninstall button
uninstall_icon = gtk.Image()
uninstall_icon.set_from_file("/home/%s/.tux_search/icons/uninstall.png" % get_username)
uninstall_button = gtk.ToolButton(label="Uninstall!", icon_widget=uninstall_icon)
toolbar.insert(uninstall_button, 0)
uninstall_button.connect("clicked", self.uninstall_program)
#install button
install_icon = gtk.Image()
install_icon.set_from_file("/home/%s/.tux_search/icons/working_tux.png" % get_username)
install_button = gtk.ToolButton(label="Install", icon_widget=install_icon)
toolbar.insert(install_button, 1)
install_button.connect("clicked", self.install_selected)
toolbar.show()
#search button
search_icon = gtk.Image()
search_icon.set_from_file("/home/%s/.tux_search/icons/tux_search.png" % get_username)
search_button = gtk.ToolButton(label="Search Again", icon_widget=search_icon)
toolbar.insert(search_button, 2)
search_button.connect("clicked", self.create_search)
table_vbox.show()
self.aptitude_results.connect("destroy", lambda w: gtk.main_quit())
self.aptitude_results.set_default_size(600, 800)
self.aptitude_results.set_position(gtk.WIN_POS_CENTER)
self.aptitude_results.show_all()
if __name__ == "__main__":
createUI()
和林间空地文件
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkListStore" id="liststore1">
<columns>
<!-- column-name Installed? -->
<column type="gchararray"/>
<!-- column-name Package Name -->
<column type="gchararray"/>
<!-- column-name Description -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkWindow" id="window">
<property name="can_focus">False</property>
<child>
<object class="GtkVBox" id="vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="toolbar_style">both</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vadjustment">adjustment1</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<object class="GtkTreeView" id="treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore1</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
由于我无法发布屏幕截图,因此可以找到我的photobucket屏幕截图
http://i57.photobucket.com/albums/g239/Stratus_ss/cli.png