import tkinter as tk import re from tkinter import ttk from tem_pip import runpip class Pip_interface(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self, parent) self.parent = parent self.parent.title("PIP Package Manager") self.gui_height = parent.winfo_reqheight() self.gui_width = parent.winfo_reqwidth() # use for installed package tab self.installed_list = None self.lastest_version = None self.package_detail = None self.installed_and_lastest_list = [] self.canvas_text_id = None # end for installed package tab # use for search tab self.search_result = None # end for search tab self._create_panel() self.parent.resizable("false", "false") def _create_panel(self): nb = ttk.Notebook(self.parent) nb.pack(fill="both") self._create_search_tab(nb) self._create_installed_package_tab(nb) def _create_search_tab(self, nb): frame = ttk.Frame(nb) frame.pack() nb.add(frame, text="Search") def _create_installed_package_tab(self, nb): frame = ttk.Frame(nb) frame.pack() paned_window = ttk.PanedWindow(frame, orient="horizontal") install_button = ttk.Button(frame, text="Update") uninstall_button = ttk.Button(frame, text="Uninstall") paned_window.pack(fill="both") install_button.pack(side="right") uninstall_button.pack(side="right") # installed package frame installed_package_frame = ttk.LabelFrame(paned_window, text="Installed Package") self._add_lastest_version_to_installed_list() installed_package_treeview = ttk.Treeview(installed_package_frame, columns=("Package", "Version", "Lastest"), show="headings", height=30) installed_package_treeview.heading("Package", text="Package") installed_package_treeview.heading("Version", text="Version") installed_package_treeview.heading("Lastest", text="Lastest") self.display_data("treeview", installed_package_treeview) treeview_v_scrollbar = ttk.Scrollbar(installed_package_frame, orient="vertical", command=installed_package_treeview.yview) installed_package_treeview.configure(yscrollcommand=treeview_v_scrollbar.set) installed_package_treeview.grid(sticky="news") treeview_v_scrollbar.grid(column=1, row=0, sticky="ns") # end installed package frame # description frame description_frame = ttk.LabelFrame(paned_window, text="Description") description_text = tk.Canvas(description_frame, height=555, width=600, scrollregion=(0, 0, 1200, 1400)) description_text.xview_moveto(0.2) description_text.yview_moveto(0.3) text_canvas_v_scrollbar = ttk.Scrollbar(description_frame, orient="vertical", command=description_text.yview) text_canvas_h_scrollbar = ttk.Scrollbar(description_frame, orient="horizontal", command=description_text.xview) description_text.configure(yscrollcommand=text_canvas_v_scrollbar.set, xscrollcommand=text_canvas_h_scrollbar.set) installed_package_treeview.bind("", lambda x: self._get_and_display_package_detail ( installed_package_treeview, description_text ) ) description_text.grid(sticky="news") text_canvas_v_scrollbar.grid(column=1, row=0, sticky="ns") text_canvas_h_scrollbar.grid(column=0, row=1, sticky="ew") # end description frame paned_window.add(installed_package_frame) paned_window.add(description_frame) nb.add(frame, text="Installed Package") def get_data(self, command_string): """ """ try: command, option = command_string.split(" ") except ValueError: command = command_string option = None if command == "search": status, out, err = runpip("search {}".format(option)) pattern = re.compile("(\w+.*?)\s\(([0-9a-z.]+)\)\s+-") self.search_result = pattern.findall(out) elif command == "list": if option is None: status, out, err = runpip("list") self.installed_list = out.split("\n") elif option == "--outdated": status, out, err = runpip("list --outdated") self.lastest_version = out.split("\n") elif command == "show": status, out, err = runpip("show {}".format(option)) self.package_detail = out def display_data(self, widget_type, widget_name): """ The type are: treeview canvas_text """ if widget_type == "treeview" and self.installed_and_lastest_list is not None: for i in range(0, len(self.installed_and_lastest_list)): widget_name.insert("", "end", "", values=tuple(self.installed_and_lastest_list[i])) elif widget_type == "canvas_text" and self.package_detail is not None: if self.canvas_text_id is not None: widget_name.delete(self.canvas_text_id) self.canvas_text_id = widget_name.create_text(600, 700, text=self.package_detail) else: self.canvas_text_id = widget_name.create_text(600, 700, text=self.package_detail) # from here is the function for installed package frame def _add_lastest_version_to_installed_list(self): self.get_data("list") self.get_data("list --outdated") self.installed_list.pop() # do not know why got last empty item in list self.lastest_version.pop() # below code is used to clean the above two list so I can compare for update version temp_installed_list = [] installed_pattern = re.compile("(\w+.*?)\s\(([0-9a-z.]+)\)") temp_lastest_list = [] lastest_pattern = pattern = re.compile("(\w+.*?)\s\(.*?\:\s([0-9a-z.]+)\s") for i in range(0, len(self.installed_list)): temp_installed_list.insert(i, list(installed_pattern.findall(self.installed_list[i])[0])) for i in range(0, len(self.lastest_version)): temp_lastest_list.insert(i, list(lastest_pattern.findall(self.lastest_version[i])[0])) for x in range(0, len(temp_lastest_list)): for y in range(0, len(temp_installed_list)): if temp_lastest_list[x][0] == temp_installed_list[y][0]: temp_list = [ temp_installed_list[y][0], temp_installed_list[y][1], temp_lastest_list[x][1] ] self.installed_and_lastest_list.append(temp_list) else: temp_list = [ temp_installed_list[y][0], temp_installed_list[y][1], temp_installed_list[y][1] ] self.installed_and_lastest_list.append(temp_list) # end here # end function for installed package frame # from here is the function for description frame def _get_and_display_package_detail(self, treeview, widget_name): item = treeview.selection()[0] self.get_data("show {}".format(treeview.item(item)["values"][0])) self.display_data("canvas_text", widget_name) # end function for description frame if __name__ == "__main__": root = tk.Tk() Pip_interface(root) root.mainloop()