[pygtk] Confused by multiple selections

Alan alfraealba at googlemail.com
Fri Oct 15 06:48:44 WST 2010


Hi

I am attempting to incorporate multiple selections of a list-store into
a program I am working on. To get my head round it, I have written the
following test program (written in python-gtk2-2.17 on ubuntu 10.4):

=======================================================================
#!/usr/bin/env python


import pygtk
pygtk.require('2.0')
import gtk
import os
from datetime import datetime
import logging
# Turn logging on or off
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s
%(levelname)s: %(message)s',datefmt='%Y-%m-%d %H:%M:%S') # Turn logging
on 
#logging.basicConfig() # Turn debugging off


class BasicTreeViewExample:

	pathlist = []


	# close the window and quit
	def delete_event(self, widget, event, data=None):
		gtk.main_quit()
		return False

	def button_cb(self, widget,  data=None):
		print ("button pressed")
		logging.debug("contents of pathlist" + str(self.pathlist))
		logging.debug("length of pathlist=" + str(len(self.pathlist)))
		logging.debug(str("value of pathlist[0]=" + str(self.pathlist[0])))
		model = self.treeview.get_model()
		for x in self.pathlist:
			iter = model.get_iter(x)
			if iter != None :
				print ("value or select store=" + model.get_value(iter, 1))


	def add_data(self):
		# we'll add some data now - 4 rows 
		piter = self.liststore.append(["acdc - highway to hell",  "$MUSIC\acdc
\highway"])
		piter = self.liststore.append(["Saxon - inner sanctum",  "$MUSIC\saxon
\inner"])
		piter = self.liststore.append(["Gun - Greatest Hist",  "$MUSIC\gun
\greatest_hits"])
		piter = self.liststore.append(["ABC - Look of love",  "$music\abc
\look_of_love"])

	def selecttest1(self, widget):
		#get data from highlighted selection
		treeselection = widget.get_selection()

		(model, self.pathlist) = treeselection.get_selected_rows()
		logging.debug("lenght of pathlist=" + str(len(self.pathlist)))

	def my_treeview(self):
		# create a ListStore with one string column to use as the model
		self.liststore = gtk.ListStore(str, str)
		self.add_data()
		self.treeview = gtk.TreeView(self.liststore)
		self.treeview.set_headers_visible(False)
		# create the TreeViewColumn to display the data
		self.tvcolumn = gtk.TreeViewColumn()
		# add tvcolumn to treeview
		self.treeview.append_column(self.tvcolumn)
		# create a CellRendererText to render the data
		self.cell = gtk.CellRendererText()
		# add the cell to the tvcolumn and allow it to expand
		self.tvcolumn.pack_start(self.cell, True)
		# set the cell "text" attribute to column 0 - retrieve text
    # from that column in treestore
		self.tvcolumn.add_attribute(self.cell, 'text', 0)
		# make it searchable
		self.treeview.set_search_column(0)
		# Allow drag and drop reordering of rows
		self.treeview.set_reorderable(False)
		return (self.treeview)

 	def __init__(self):
		# Create a new window
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.window.set_title("Music Collection")
		self.window.set_size_request(500, 200)
		self.window.connect("delete_event", self.delete_event)          	
		table1 = gtk.Table(1, 2, False)
		table1.set_row_spacings( 5)
		table1.set_col_spacings(5)
		self.window.add(table1)  
		# create the TreeView using liststore
		self.treeview = self.my_treeview() 
		treeselection = self.treeview.get_selection()
		treeselection.set_mode(gtk.SELECTION_MULTIPLE)
		# values colx, coly, roxx, rowy
		table1.attach(self.treeview, 0, 1, 0, 1)
		my_button  = gtk.Button("click here")
		table1.attach(my_button, 1,2, 0, 1)
		self.treeview.connect('cursor-changed', self.selecttest1)
		my_button.connect('clicked', self.button_cb)
		self.window.show_all()
		table1.show()

def main():
	gtk.main()

if __name__ == "__main__":
    tvexample = BasicTreeViewExample()
    main()
=====================================================

The problem is that if more than one item is selected, say two, you have
to click on the second item twice for it to register when the button is
clicked.

I tried the treeselection.selected_foreach function as well:


==========================================================
#!/usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import os
from datetime import datetime
import logging
# Turn logging on or off
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s
%(levelname)s: %(message)s',datefmt='%Y-%m-%d %H:%M:%S') # Turn logging
on 
#logging.basicConfig() # Turn debugging off


class BasicTreeViewExample:

	pathlist = []

	# close the window and quit
	def delete_event(self, widget, event, data=None):
		gtk.main_quit()
		return False

	def button_cb(self, widget,  data=None):
		print ("button pressed")
		logging.debug("contents of pathlist" + str(self.pathlist))
		logging.debug("self =" + str(self) + " widget=" + str(widget))
		logging.debug("length of pathlist" + str(len(self.pathlist)))
		logging.debug(str("value of pathlist[0]=" + str(self.pathlist[0])))
		model = self.treeview.get_model()
		iter = model.get_iter(self.pathlist[0])
		if iter != None :
			logging.debug( "value or select store=" + model.get_value(iter, 0))
			logging.debug(iter)


	def add_data(self):
		# we'll add some data now - 4 rows 
		piter = self.liststore.append(["acdc - highway to hell",  "$MUSIC\acdc
\highway"])
		piter = self.liststore.append(["Saxon - inner sanctum",  "$MUSIC\saxon
\inner"])
		piter = self.liststore.append(["Gun - Greatest Hist",  "$MUSIC\gun
\greatest_hits"])
		piter = self.liststore.append(["ABC - Look of love",  "$music\abc
\look_of_love"])

	def foreach_cb(self,model, path, iter):
    #list.append(path)
		logging.debug("inside foreeach_cb")
		logging.debug("path=" + str(path))
		logging.debug("iter=" + str(iter))
		if iter != None :
			logging.debug ("value or select store=" + model.get_value(iter, 1))

	def selecttest1(self, widget):
		#get data from highlighted selection
		treeselection = widget.get_selection()
		treeselection.set_mode(gtk.SELECTION_MULTIPLE)
		treeselection.selected_foreach(self.foreach_cb)

	def my_treeview(self):
		# create a ListStore with one string column to use as the model
		self.liststore = gtk.ListStore(str, str)
		self.add_data()
		self.treeview = gtk.TreeView(self.liststore)
		self.treeview.set_headers_visible(False)
		# create the TreeViewColumn to display the data
		self.tvcolumn = gtk.TreeViewColumn()
		# add tvcolumn to treeview
		self.treeview.append_column(self.tvcolumn)
		# create a CellRendererText to render the data
		self.cell = gtk.CellRendererText()
		# add the cell to the tvcolumn and allow it to expand
		self.tvcolumn.pack_start(self.cell, True)
		# set the cell "text" attribute to column 0 - retrieve text
        # from that column in treestore
		self.tvcolumn.add_attribute(self.cell, 'text', 0)
		# make it searchable
		self.treeview.set_search_column(0)
		# Allow drag and drop reordering of rows
		self.treeview.set_reorderable(False)
		return (self.treeview)

 	def __init__(self):
		# Create a new window
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)

		self.window.set_title("Music Collection")
		self.window.set_size_request(500, 200)
		self.window.connect("delete_event", self.delete_event)         	
		table1 = gtk.Table(1, 2, False)
		table1.set_row_spacings( 5)
		table1.set_col_spacings(5)
		self.window.add(table1)   
		# create the TreeView using liststore
		self.treeview = self.my_treeview() 	
		# values colx, coly, roxx, rowy
		table1.attach(self.treeview, 0, 1, 0, 1)
		my_button  = gtk.Button("click here")
		table1.attach(my_button, 1,2, 0, 1)
		self.treeview.connect('cursor-changed', self.selecttest1)
		my_button.connect('clicked', self.button_cb)
		self.window.show_all()
		table1.show()

def main():
	gtk.main()

if __name__ == "__main__":
    tvexample = BasicTreeViewExample()
    main()

=========================================

Although the button isn't fully functioning properly as I am only using
the debug messages to see it's behaviour. Unfortunately it is behaving
the same way as first example.

I don't know if I am missing something. Can someone please help.

Thanks in advance.

Alan.




More information about the pygtk mailing list