Всем доброго времени суток. Не пойму появления «пустого» объекта treeview path при подключении treeview к сигналу 'cursor_changed'. При каждом первом (только первом) срабатывании функции по сигналу первая попытка получить treepath приводит к TypeError. Последующие уже нормально. Приходится либо через try либо через if отлавливать nonetype obj.
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import re
import gi
import subprocess
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk, Gdk
class Get_Data:
def __init__(self):
self.s_list = []
def ret_soft_info(self, n_soft):
self.s_list = []
with subprocess.Popen(["snap", "info", n_soft], stdout=subprocess.PIPE) as proc:
self.s_list = proc.stdout.read().decode('utf-8')
return self.s_list
def ret_soft_find(self, n_soft):
c = []
self.s_list = []
with subprocess.Popen(["snap", "find", n_soft], stdout=subprocess.PIPE) as proc:
b = re.findall(r'(.+?)\n', proc.stdout.read().decode('utf-8'), re.M)
if b == []:
return ['', 'No matching snaps']
for x in b:
c.append(re.findall(r'^(.+?)\s{2,}(.+?)\s{2,}(.+?)\s{2,}(.+?)\s{2,}(.+?)$', x, re.M))
for x in c:
for z in x:
self.s_list.append(list(z))
return self.s_list
# Функция отображения существующих пакетов
def ret_soft_list(self):
z = []
s_list = []
with subprocess.Popen(["snap", "list"], stdout=subprocess.PIPE) as proc:
for x in re.findall(r'(^.*?$)', proc.stdout.read().decode('utf-8'), re.MULTILINE):
y = re.sub(r'\s{2,}', ' ', x)
if y != '':
z.append(y)
for x in z:
s_list.append(x.split(' '))
return s_list
class TreeViews(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="View snap packet")
self.set_border_width(5)
self.set_default_size(700, 490)
self.set_position(Gtk.WindowPosition(1))
self.m_gdata = Get_Data()
self.state_b = "off"
self.state_find = "off"
self.m_run_prog = ''
self.m_menu_r = Gtk.Menu()
self.m_menu_run = Gtk.MenuItem("Run")
self.m_menu_r.append(self.m_menu_run)
self.m_menu_run.connect("activate", self.run_snap_prog)
self.m_menu_r.show_all()
self.m_menu_i = Gtk.Menu()
self.m_menu_inst = Gtk.MenuItem("Install")
self.m_menu_i.append(self.m_menu_inst)
self.m_menu_inst.connect("activate", self.install_snap_prog)
self.m_menu_i.show_all()
self.treeview = Gtk.TreeView.new()
self.treeview.connect('cursor_changed', self.curs_chenge)
self.treeview.connect("button_press_event", self.mouse_r_click)
self.treeview.props.activate_on_single_click = True
self.treeview.props.enable_grid_lines = True
self.treeview.props.enable_tree_lines = True
self.treeview.props.enable_search = True
self.treeview.props.search_column = 0
self.m_fixed = Gtk.Fixed()
self.add(self.m_fixed)
self.scrollable_t = Gtk.ScrolledWindow()
self.scrollable_t.set_shadow_type(Gtk.ShadowType(1))
self.scrollable_t.set_size_request(650, 350)
self.scrollable_t.add(self.treeview)
self.m_fixed.put(self.scrollable_t, 20, 1)
self.m_label = Gtk.Label('')
self.m_label.set_selectable(True)
self.m_frame = Gtk.Frame.new('Info')
self.m_frame.set_shadow_type(Gtk.ShadowType(2))
self.m_frame.set_size_request(650, 50)
self.m_frame.add(self.m_label)
self.m_fixed.put(self.m_frame, 20, 360)
self.m_entry = Gtk.Entry.new_with_buffer(Gtk.EntryBuffer.new(None, -1))
self.m_entry.connect('key-press-event', self.on_ent_pres)
self.m_fixed.put(self.m_entry, 20, 430)
self.m_checkbutton = Gtk.CheckButton("Find paket")
self.m_checkbutton.connect("toggled", self.check_b_find_toggled, 'f')
self.m_fixed.put(self.m_checkbutton, 190, 435)
self.m_button_сlear = Gtk.Button.new_with_label("Clear")
self.m_button_сlear.connect("clicked", self.on_click_button_c)
self.m_button_сlear.set_size_request(100, 25)
self.m_fixed.put(self.m_button_сlear, 300, 430)
self.m_button_present = Gtk.Button.new_with_label("InSystem")
self.m_button_present.set_size_request(100, 25)
self.m_button_present.connect("clicked", self.present_pakets)
self.m_fixed.put(self.m_button_present, 410, 430)
self.m_button_exit = Gtk.Button.new_with_label("Exit")
self.m_button_exit.connect("clicked", self.m_exit)
self.m_button_exit.set_size_request(100, 25)
self.m_fixed.put(self.m_button_exit, 520, 430)
def install_snap_prog(self, menuitem):
if self.m_run_prog != '':
subprocess.run(["snap", "install", self.m_run_prog])
def run_snap_prog(self, menuitem):
if self.m_run_prog != '':
subprocess.Popen(["snap", "run", self.m_run_prog])
def curs_chenge(self, widget):
model = self.treeview.get_model()
mpath, mcol = self.treeview.get_cursor()
print(mpath, mcol)
if mpath == None:
return False
else:
m_iter = model.get_iter(mpath)
self.m_run_prog = model.get_value(m_iter, 0)
self.m_label.set_text(self.m_run_prog)
self.m_label.set_tooltip_text(self.m_gdata.ret_soft_info(self.m_run_prog))
def mouse_r_click(self, widget, event):
if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3 and self.state_find == 'off':
self.m_menu_r.popup(None, None, None, None, event.button, event.time)
if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3 and self.state_find == 'on':
self.m_menu_i.popup(None, None, None, None, event.button, event.time)
def check_b_find_toggled(self, button, name):
if button.get_active():
self.state_b = "on"
else:
self.state_b = "off"
def on_ent_pres(self, entry_obj, event_key):
if Gdk.keyval_name(event_key.keyval) == 'Return':
if self.state_b == "on":
self.find_pakets()
self.m_checkbutton.set_active(False)
# Функция поиска пакетов
def find_pakets(self):
self.treeview.set_model(Gtk.ListStore(str, str, str, str, str))
for software_ref in self.m_gdata.ret_soft_find(self.m_entry.get_text())[1:]:
if 'No matching snaps' in software_ref:
self.m_label.set_text('No matching snaps for "' + self.m_entry.get_text() + '"')
return False
else:
self.treeview.get_model().append(software_ref)
for i, column_title in enumerate(["Name", "Version", "Publisher", "Notes", "Summary"]):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
column.set_expand(True)
self.treeview.append_column(column)
self.show_all()
self.state_find = 'on'
# Функция отображения существующих пакетов
def present_pakets(self, batton):
self.treeview.set_model(Gtk.ListStore(str, str, str, str, str, str))
for software_ref in self.m_gdata.ret_soft_list()[1:]:
self.treeview.get_model().append(software_ref)
for i, column_title in enumerate(["Name", "Version", "Rev", "Tracking", "Publisher", "Notes"]):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
column.set_expand(True)
self.treeview.append_column(column)
self.show_all()
self.state_find = 'off'
def on_click_button_c(self, button):
for x in self.treeview.get_columns():
self.treeview.remove_column(x)
self.state_find = 'off'
self.m_entry.set_text('')
self.m_label.set_text('')
self.m_label.set_tooltip_text('')
def m_exit(self, button):
Gtk.main_quit()
win = TreeViews()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
<Gtk.ListStore object at 0x7f00ee5b8af8 (GtkListStore at 0x296f150)> None None
Traceback (most recent call last):
File "Gtk_win_3.py", line 152, in curs_chenge
m_iter = model.get_iter(mpath)
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 836, in get_iter
path = self._coerce_path(path)
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 811, in _coerce_path
return TreePath(path)
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 1175, in __new__
path = ":".join(str(val) for val in path)
TypeError: 'NoneType' object is not iterable