GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sat Oct 25, 2014 10:05 pm

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Validating user input with TreeView and CellRendererText
PostPosted: Fri Dec 04, 2009 5:26 am 
Offline
Familiar Face

Joined: Fri Dec 04, 2009 5:01 am
Posts: 5
Location: Sydney
EDIT: 2009/12/04 - Fixed formatting, added a source code example

Hi All,
I have a TreeView with a single column that holds a CellRendererText component set to editable.

What I would like to do is, validate the users input into the text box, if it does not match some criteria, I would like to refocus the input on that cell so that the user cannot leave until it is correct.

As far as I can tell, this is pretty simple. I have a function "on_edited" that I connect to the text renderer "edited" event. If the users input does not match my criteria I reset the cursor and set the cell to editing using set_cursor(path,col,True). Eg:

(pseudo-code)

Code:
on_edited(cell,path,new_text)
{
    if (new_text != "42")
    {
        col = treeView1.get_column(0);
        treeView1.set_cursor(path,col,True);
        return;
    }

    print "Success!"
}



However, when I do this, if the text is not "42" II get an internal GTK failure:

GtkWarning: _gtk_tree_view_column_start_editing: assertion 'tree_column->editable_widget == NULL' failed

What am I doing wrong here? This seems like a perfectly logical control flow?

Thanks
Matt

Source code:

Glade file:
Code:
<?xml version="1.0"?>
<glade-interface>
  <!-- interface-requires gtk+ 2.16 -->
  <!-- interface-naming-policy project-wide -->
  <widget class="GtkWindow" id="main">
    <property name="visible">True</property>
    <property name="title" translatable="yes">Main</property>
    <property name="window_position">center</property>
    <child>
      <widget class="GtkTreeView" id="treeview1">
        <property name="width_request">200</property>
        <property name="height_request">300</property>
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="search_column">0</property>
        <property name="level_indentation">5</property>
      </widget>
    </child>
  </widget>
</glade-interface>


Python source:
Code:
#!/usr/bin/env python

import gtk
import gtk.glade
import gobject


class MainWindow:
    def __init__(self):
        self.gladefile = "tree_test.glade"
        self.wTree     = gtk.glade.XML(self.gladefile)
        self.window    = self.wTree.get_widget("main")
        self.window.connect("destroy",gtk.main_quit)       
   
        #Set up the tree view
        self.treeView1 = self.wTree.get_widget("treeview1")
        self.store     = gtk.ListStore(gobject.TYPE_STRING)       
        textCell       = gtk.CellRendererText()
        textCell.set_property("editable",True)
        self.treeView1.set_model(self.store)
        self.treeView1.append_column(gtk.TreeViewColumn("Text",textCell,text=0))
       
        textCell.connect("edited", self.on_edit)
       
        #Add a line to the tree view
        iter = self.store.append(["line1"])
        path = self.store.get_path(iter)
         
        #Select the line
        self.treeView1.set_cursor(path)
   
    def on_edit(self,cell,path,new_text):
        if(new_text != "42"):
            col = self.treeView1.get_column(0)
            self.treeView1.set_cursor(path,col,True)
           
            return
       
        self.store.clear()
        self.store.append(["OK"])


try:
    main = MainWindow()
    gtk.main()
except:
    pass


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 04, 2009 9:14 am 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello and welcome to the GTK+ forums.

I tested your code under GTK+-2.18.3 and PyGTK-2.16 and it works flawlessly.

Why would that error occur at all? It seems that cell renderer is not destroying editable widget before emitting "edited" signal. What version of GTK+ are you using?

Tadej


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 04, 2009 11:20 am 
Offline
Familiar Face

Joined: Fri Dec 04, 2009 5:01 am
Posts: 5
Location: Sydney
Hi Tadej,
Thanks so much for for the kind welcome and quick response. I'm obviously quite new to GTK development.

I have tried on my work machine and on my home machine. Work is a Centos5-64bit machine. Home is an Ubuntu 9.10-32bit. Both behave exactly the same way. ie

Work:
Code:
ws015:~$ ./test.py
./test.py:35: GtkWarning: _gtk_tree_view_column_start_editing: assertion `tree_column->editable_widget == NULL' failed
  self.treeView1.set_cursor(path,col,True)


Home:
Code:
mgrosvenor@ubuntu:~/workspace/pygtk_treeview_test/src$ ./test.py
./test.py:35: GtkWarning: _gtk_tree_view_column_start_editing: assertion `tree_column->editable_widget == NULL' failed
  self.treeView1.set_cursor(path,col,True)


Figuring out the version numbers is a little tricky. As far as I can tell, work is running gtk2-2.10.4-20.el5.x86_64 and pygtk2-2.10.1-12.el5.x86_64.

Home is running libgtk2 2.18.3-1ubuntu2 and python-gtk2 2.16.0-0ubuntu1.

To produce the error, I run the app, click once on "line1" to edit the treeview text box, then click once on some white space in the treeview. In both places it fails the same way.

Thanks again.
Matt


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 04, 2009 11:25 am 
Offline
Familiar Face

Joined: Fri Dec 04, 2009 5:01 am
Posts: 5
Location: Sydney
PS.

Quote:
It seems that cell renderer is not destroying editable widget before emitting "edited" signal.


Yes it does. So I tried this.

Code:
  def on_edit(self,cell,path,new_text):
        if(new_text != "42"):
            col = self.treeView1.get_column(0)
           
           #Make the widget not editable
           self.treeView1.set_cursor(path,col,False)

          #Make the widget editable again
           self.treeView1.set_cursor(path,col,True)
           
            return


But it does not help. Same error.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 04, 2009 1:36 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello.
mgrosvenor wrote:
To produce the error, I run the app, click once on "line1" to edit the treeview text box, then click once on some white space in the treeview. In both places it fails the same way.

This is one important piece of information. I tested you application by pressing enter to confirm my input and by pressing escape to ignore the changes and both of those scenarios produced proper results. Your method does indeed produce bad results. I'm almost certain this could be a GTK+ bug, since clicking outside the entry should not trigger emission of "edited" signal (clicking outside the entry means that operation has been canceled).

I'll investigate this further and see what can I come up with. (I don't have access to my debug build of GTK+ right now.)

Tadej


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 07, 2009 12:10 am 
Offline
Familiar Face

Joined: Fri Dec 04, 2009 5:01 am
Posts: 5
Location: Sydney
Hi again,

Thanks a lot for your kind offer. This "bug" is a bit of a hold up for me at the moment. If there is any way that I can assist, please let me know.

Thanks again.
Matt


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 09, 2009 9:26 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello.

As promised, I did some research about this on my debug build of GTK+ and found some interesting things. To make long story short, when you stop editing your text in cell renderer and click somewhere inside tree view, editing operation is considered to be completed successfully and "edited" signal is emitted.

Problems arise from the fact that "edited" signal is emitted before entry is destroyed, which causes application to lock badly. I'll eventually write down a patch that will make this operation a bit safer, but since you need this functionality now, that work won't help you much (I'm not a GTK+ developer and getting my patch accepted can take quite some time).

To make your application operational in the mean time, you can do the following:
Code:
#!/usr/bin/env python

import gtk
import gtk.glade
import glib
import gobject


class MainWindow:
   def __init__(self):
      self.gladefile = "scroll.glade"
      self.wTree    = gtk.glade.XML(self.gladefile)
      self.window   = self.wTree.get_widget("main")
      self.window.connect("destroy",gtk.main_quit)      
   
      #Set up the tree view
      self.treeView1 = self.wTree.get_widget("treeview1")
      self.store    = gtk.ListStore(gobject.TYPE_STRING)      
      textCell      = gtk.CellRendererText()
      textCell.set_property("editable",True)
      self.treeView1.set_model(self.store)
      self.treeView1.append_column(gtk.TreeViewColumn("Text",textCell,text=0))
      
      textCell.connect("edited", self.on_edit)
      
      #Add a line to the tree view
      iter = self.store.append(["line1"])
      path = self.store.get_path(iter)
      
      #Select the line
      self.treeView1.set_cursor(path)
   
   def on_edit(self,cell,path,new_text):
      print new_text
      if(new_text != "42"):
         col = self.treeView1.get_column(0)
         glib.idle_add( self.restart_edit, path, col )
         
         return
      
      self.store.clear()
      self.store.append(["OK"])

   def restart_edit( self, path, col ):
      self.treeView1.set_cursor(path,col,True)
      return False


try:
   main = MainWindow()
   gtk.main()
except:
   pass

This code should work as expected. What is the main catch? glib.idle_add function gives tree view time to clean after itself before restarting edit (more precisely, re-edit is started asynchronously now, while before this was synchronous action).

Tadej


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 11, 2009 12:45 am 
Offline
Familiar Face

Joined: Fri Dec 04, 2009 5:01 am
Posts: 5
Location: Sydney
Hi Tadej,
Thanks so much for the all the effort! I really appreciate it!.

Thanks also for the workaround. I am developing on a Centos 5 machine. So, the latest patches are some years away for us!

I'll give the work around a try.

Thanks again.
Matt


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group