By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,837 Members | 1,357 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,837 IT Pros & Developers. It's quick & easy.

It is not possible to create a recursive function over a pyGTK treeStore

P: n/a
Hello,

I would like to create a minimalist file browser using pyGTK.

Having read lot of tutorials, it seems to me that that in my case, the
best solution is
to have a gtk.TreeStore containing all the files and folders so that
it would map the
file system hierarchy.

I wrote a recursive function that would go through the file system
tree.

My problem is that a sub-node of a gtk.TreeStore is not a
gtk.TreeStore, but
a gtk.TreeIter. And gtk.treeter has almost no functions I would be
able to use (like "append")
Therefore I can not explore the whole file system.

Do you have another way so that I would be able to put all the file
system hierarchy
into a gtk.TreeStore?
I was quite happy with my recursive solution ...

===================================
code :
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk, gobject, os
prefdir="/tmp/a"

class InfoModele:

def matchPathTreetoModelTree(self, path, treeStoreNode):
files = [f for f in os.listdir(path) if f[0] <'.']
for i in range(len(files)):
if os.path.isfile(path+'/'+files[i]):
print path+'/'+files[i]+" is a file"
treeStoreNode.append( None, (path+'/'+files[i], None) )
if os.path.isdir(path+'/'+files[i]): #is a directory, go
recursively
print path+'/'+files[i]+" is a directory"
mother = self.tree_store.append( None, (path+'/'+files[i], None) )
self.matchPathTreetoModelTree(path+'/'+files[i], mother)

def __init__(self):
self.tree_store = gtk.TreeStore( gobject.TYPE_STRING,
gobject.TYPE_STRING)
path=prefdir
self.matchPathTreetoModelTree(prefdir, self.tree_store)

if __name__ == "__main__":
i=InfoModele()

=================================
file system :
a
|-ab/
|-abc/
|-abcd

================================
Program output :
/tmp/a/ab is a directory
/tmp/a/ab/abc is a file
Traceback (most recent call last):
File "question.py", line 28, in <module>
i=InfoModele()
File "question.py", line 25, in __init__
self.matchPathTreetoModelTree(prefdir, self.tree_store)
File "question.py", line 20, in matchPathTreetoModelTree
self.matchPathTreetoModelTree(path+'/'+files[i], mother)
File "question.py", line 16, in matchPathTreetoModelTree
treeStoreNode.append( None, (path+'/'+files[i], None) )
AttributeError: 'gtk.TreeIter' object has no attribute 'append'

Jun 29 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
se***************@gmail.com a écrit :
Hello,

I would like to create a minimalist file browser using pyGTK.

Having read lot of tutorials, it seems to me that that in my case, the
best solution is
to have a gtk.TreeStore containing all the files and folders so that
it would map the
file system hierarchy.

I wrote a recursive function that would go through the file system
tree.

My problem is that a sub-node of a gtk.TreeStore is not a
gtk.TreeStore, but
a gtk.TreeIter. And gtk.treeter has almost no functions I would be
able to use (like "append")
Therefore I can not explore the whole file system.

Do you have another way so that I would be able to put all the file
system hierarchy
into a gtk.TreeStore?
Sorry, no anwser to that - I don't do much GUI programming. But asking
on GTK mailing-list may be a good idea.
I was quite happy with my recursive solution ...
A couple of comments on the code:
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk, gobject, os
prefdir="/tmp/a"

class InfoModele:
Do yourself (and the world) a favour: use new-styles classes. And while
we're at it, be consistant wrt/ naming:

class InfoModel(object):
def matchPathTreetoModelTree(self, path, treeStoreNode):
<side-note>
You're of course free to use mixedCase, but unless this is a
project-specific (or workplace-specific) convention, it might be better
to stick to pep08 (all_lower_with_underscores). But if you choose
mixedCase, at least be consistant
(ie : self.tree_store =self.treeStore)
</side-note>
files = [f for f in os.listdir(path) if f[0] <'.']
could also use str.startswith here:

files = [f for f in os.listdir(path) \
if not f.startswith('.')]

But I don't see the point of this listcomp when you could filter out
special names in the for loop.
for i in range(len(files)):
Coming from a C-like language ?-)

The for loop in Python is much smarter than this. You don't have to use
an explicit indexing, you can just iterate over the sequence, ie,
instead of:

for i in range(len(files)):
the_file = files[i]
do_something_with(the_file)

You can do:

for the_file in files:
do_something_with(the_file)

NB : if you need the index for any other reason, you can use enumerate(seq):

for i, the_file in enumerate(files):
print >sys.stderr, "file #%s" % i
do_something_with(the_file)

if os.path.isfile(path+'/'+files[i]):
print path+'/'+files[i]+" is a file"
treeStoreNode.append( None, (path+'/'+files[i], None) )
My...

1/: use os.path.join()
2/: avoid recomputing the same value thrice or more, especially if
within a loop
3/ (optional, but good to know): within loops, make the often used
methods locals - this will save *a lot* of lookup time (since Python is
highly dynamic, the compiler cannot optimize much here).
4/ stdout is for normal program outputs. Error messages, debug
informations et al should go to stderr
if os.path.isdir(path+'/'+files[i]):
Note that you should'nt do this test if the previous succeeded, since
both are exclusive. IOW, use a elif.
> print path+'/'+files[i]+" is a directory"
mother = self.tree_store.append(None, (path+'/'+files[i], None))
You certainly have an error here. If you're already in a subdirectory,
you don't want to create the node on the root but on the parent's
directory node - IOW, dont use self.tree_store, but treeStoreNode. Which
allow to further simplify the code (cf below)
> self.matchPathTreetoModelTree(path+'/'+files[i], mother)

def __init__(self):
self.tree_store = gtk.TreeStore( gobject.TYPE_STRING,
gobject.TYPE_STRING)
path=prefdir
This should be an argument of the initializer
self.matchPathTreetoModelTree(prefdir, self.tree_store)
(snip)

Suggestion:

class InfoModel(object):
def __init__(self, path):
self.basepath = path
self.treeStore = gtk.TreeStore(
gobject.TYPE_STRING,
gobject.TYPE_STRING
)
self.matchPathTreetoModelTree(path, self.treeStore)

def matchPathTreetoModelTree(self, path, treeStoreNode):
isdir = os.path.isdir
join = os.path.join
append= treeStoreNode.append
recurse = self.matchPathTreetoModelTree

filenames = os.listdir(path)
for filename in filenames:
if filename.startswith('.'):
continue

filepath = join(path, filename)
# tracing for debug - assuming this will disappear
# before going to prod, it's ok to repeat the call
# to isdir() here
print >sys.stderr, "%s is a %s" \
% (filepath, ('file', 'dir')[isdir(filepath)])

# nb: you may want to filter out non-regular files
# like devices, sockects etc here
newnode = append(None, (filepath, None))
if isdir(filepath):
recurse(filepath, newnode)
HTH
Jun 29 '07 #2

P: n/a
A little update : I finally found an example of a file browser using
gtkTreestore that parse the file system recursively :
http://www.koders.com/python/fidDB37...xtensions#L113

I still need to check how it works, but I am sure that it will answer
my question.
Thank you
On 29 juin, 13:30, sebastien.abei...@gmail.com wrote:
Hello,

I would like to create a minimalist file browser using pyGTK.

Having read lot of tutorials, it seems to me that that in my case, the
best solution is
to have a gtk.TreeStore containing all the files and folders so that
it would map the
file system hierarchy.

I wrote a recursive function that would go through the file system
tree.

My problem is that a sub-node of a gtk.TreeStore is not a
gtk.TreeStore, but
a gtk.TreeIter. And gtk.treeter has almost no functions I would be
able to use (like "append")
Therefore I can not explore the whole file system.

Do you have another way so that I would be able to put all the file
system hierarchy
into a gtk.TreeStore?
I was quite happy with my recursive solution ...

===================================
code :
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk, gobject, os

prefdir="/tmp/a"

class InfoModele:

def matchPathTreetoModelTree(self, path, treeStoreNode):
files = [f for f in os.listdir(path) if f[0] <'.']
for i in range(len(files)):
if os.path.isfile(path+'/'+files[i]):
print path+'/'+files[i]+" is a file"
treeStoreNode.append( None, (path+'/'+files[i], None) )
if os.path.isdir(path+'/'+files[i]): #is a directory, go
recursively
print path+'/'+files[i]+" is a directory"
mother = self.tree_store.append( None, (path+'/'+files[i], None) )
self.matchPathTreetoModelTree(path+'/'+files[i], mother)

def __init__(self):
self.tree_store = gtk.TreeStore( gobject.TYPE_STRING,
gobject.TYPE_STRING)
path=prefdir
self.matchPathTreetoModelTree(prefdir, self.tree_store)

if __name__ == "__main__":
i=InfoModele()

=================================
file system :
a
|-ab/
|-abc/
|-abcd

================================
Program output :
/tmp/a/ab is a directory
/tmp/a/ab/abc is a file
Traceback (most recent call last):
File "question.py", line 28, in <module>
i=InfoModele()
File "question.py", line 25, in __init__
self.matchPathTreetoModelTree(prefdir, self.tree_store)
File "question.py", line 20, in matchPathTreetoModelTree
self.matchPathTreetoModelTree(path+'/'+files[i], mother)
File "question.py", line 16, in matchPathTreetoModelTree
treeStoreNode.append( None, (path+'/'+files[i], None) )
AttributeError: 'gtk.TreeIter' object has no attribute 'append'

Jun 29 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.