Python GTK Treeview 上下文菜单 - 如何获取选定值

问题描述 投票:0回答:0

我有一个显示上下文菜单的 TreeView。菜单按原样显示。

但我不确定如何确定 a) 是否显示弹出窗口,和/或 b) 获取所选值。

我不关心哪个项目激活了弹出窗口,因为根据弹出窗口值采取的操作将关闭窗口,启动新查询并显示新数据。

class ListingWin(Gtk.Window):
    torrent_list_store: ListStore

    def __init__(self, torrent_list, engine_key):
        self.torrent_list = torrent_list
        self.engine = engine_key

        Gtk.Window.__init__(self, title="Torrent Listing - " + SUPPORTED_ENGINES[self.engine])

        self.connect('delete-event', self.on_destroy)
        self.entry = Gtk.Entry()
        self.entry.connect("activate", self.submit)  # enables enter key

        self.set_border_width(10)
        self.set_default_size(1000, 400)
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)

        # Setting up the grid in which the elements are to be positioned
        self.grid = Gtk.Grid()
        self.grid.set_column_homogeneous(True)
        self.grid.set_row_homogeneous(True)
        self.add(self.grid)

        # Post-process torrent_list: Create dictionary (fields 1,5) for magnet[title] lookup
        titles, magnets = [], []

        for L in self.torrent_list:
            titles.append(L[0])
            magnets.append(L[-1])

        # Stash the magnets
        self.magnet_dict = dict(zip(titles, magnets))

        # Post-process torrent_list: Create listStore (fields 1-5) without magnets
        post_list = np.array(self.torrent_list)
        store_data = post_list[:, :5].tolist()  # numpy syntax for grabbing fields 1-5 from each row

        # Create the ListStore model: "Title", "Date", "Seeds", "Leeches", "Size"
        self.torrent_list_store = Gtk.ListStore(str, str, int, int, str, float)

        for torrent_ref in store_data:
            f1 = torrent_ref[0]  # title
            f2 = torrent_ref[1]  # Date
            f3 = int(torrent_ref[2])  # Seeds
            f4 = int(torrent_ref[3])  # Leeches
            f5 = torrent_ref[4]  # Size
            #  sort MB, GB, and KiB
            if "N/A" in f5:
                s5 = 0
            elif "G" in f5:
                c5 = f5.replace('G', '')
                n1 = float(c5)
                n2 = float(1024)
                s5 = n1 * n2
            elif "M" in f5:
                c5 = f5.replace('M', '')
                s5 = float(c5)
            elif "K" in f5:
                c5 = f5.replace('KiB', '')
                s5 = float(c5)
            else:
                s5 = re.sub('[^0-9\.]', '', f5)
            row = [f1, f2, f3, f4, f5, s5]
            self.torrent_list_store.append(row)

        # Create the treeview; pass the model
        self.treeview = Gtk.TreeView()
        self.treeview.set_model(self.torrent_list_store)

        # Add columns & headers
        renderer_1 = Gtk.CellRendererText()
        renderer_2 = Gtk.CellRendererText()
        renderer_2.set_property("xalign", 1)

        column = Gtk.TreeViewColumn("Title", renderer_1, text=0)
        column.set_sort_column_id(0)
        self.treeview.append_column(column)

        column = Gtk.TreeViewColumn("Date", renderer_2, text=1)
        column.set_sort_column_id(1)
        self.treeview.append_column(column)

        column = Gtk.TreeViewColumn("Seeds", renderer_2, text=2)
        column.set_sort_column_id(2)
        self.treeview.append_column(column)

        column = Gtk.TreeViewColumn("Leeches", renderer_2, text=3)
        column.set_sort_column_id(3)
        self.treeview.append_column(column)

        #  Display field for Size (f4), sort field for Size (s5)
        column = Gtk.TreeViewColumn("Size", renderer_2, text=4)
        column.set_sort_column_id(5)
        self.treeview.append_column(column)

        # Define the buttons
        self.buttons = list()

        button = Gtk.Button(label="Download")
        button.connect("clicked", self.on_download)
        self.buttons.append(button)

        button = Gtk.Button(label="Search")
        button.connect("clicked", self.on_close)
        self.buttons.append(button)

        button = Gtk.Button(label="Quit")
        button.connect("clicked", self.on_quit)
        self.buttons.append(button)

        # Alternate engine context menu
        self.treeview.connect("button_press_event", self.show_context_menu)

        # Capture double click on row
        self.treeview.connect("row-activated", self.row_active)

        # Set multiple rows option
        self.treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)

        # Set up the layout, put the treeview in a scroll window and add the buttons in a row
        self.scrollable_treeList = Gtk.ScrolledWindow()
        self.scrollable_treeList.set_vexpand(True)

        self.grid.attach(self.scrollable_treeList, 0, 0, 8, 10)  # row,col,(h,w cells)
        self.grid.attach_next_to(self.buttons[0], self.scrollable_treeList, Gtk.PositionType.BOTTOM, 1, 1)

        for i, button in enumerate(self.buttons[1:]):
            self.grid.attach_next_to(button, self.buttons[i], Gtk.PositionType.RIGHT, 1, 1)

        self.scrollable_treeList.add(self.treeview)

    # Context menu to select another engine
    def show_context_menu(self, widget, event):
        if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
            context_menu = Gtk.Menu()
            for key, value in SUPPORTED_ENGINES.items():
                if key == self.engine:
                    continue
                cm_item = Gtk.MenuItem(label=value)
                context_menu.add(cm_item)

            context_menu.attach_to_widget(self, None)
            context_menu.show_all()
            context_menu.popup(None, None, None, None, event.button, event.time)

    # If double-click on row, download and exit
    def row_active(self, tv, col, tv_col):
        self.on_download(self)
        self.on_quit(self)

    def on_download(self, button):
        # Retrieve selected titles from ListStore
        selected_titles = []

        selection = self.treeview.get_selection()
        (self.torrent_list_store, tree_iterator) = selection.get_selected_rows()

        for path in tree_iterator:
            path_iter = self.torrent_list_store.get_iter(path)
            if path_iter is not None:
                selected_titles.append(
                    self.torrent_list_store.get_value(path_iter, 0))

        # Pass selected magnets to torrent client and exit
        for title in selected_titles:
            subprocess.Popen([TORRENT_CLIENT, self.magnet_dict[title]],
                             stdout=subprocess.DEVNULL,
                             stderr=subprocess.DEVNULL)
        self.on_quit(self)

    def submit(self, entry):
        self.destroy()
        Gtk.main_quit()

    def on_close(self, button):
        self.destroy()
        Gtk.main_quit()

    def on_destroy(self, dummy, args):
        self.destroy()
        sys.exit(0)

    def on_quit(self, button):
        self.destroy()
        sys.exit(0)


def filter_sz_age(tag):
    if tag.find('a') is not None:  # eliminate <td containing <a tags
        return False
    return tag.name == 'td' and len(tag.attrs) == 2 and (
                tag.attrs["class"] == ["forum_thread_post"] and tag.attrs["align"] == 'center')
python treeview gtk contextmenu
© www.soinside.com 2019 - 2024. All rights reserved.