Results 1 to 11 of 11

Thread: Adding validation to a QListView's edit mode

  1. #1
    Join Date
    May 2010
    Posts
    10
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Question Adding validation to a QListView's edit mode

    I want to create a QListView that validates the data entered in edit mode before saving it to the model.

    The user workflow I envision for it is:
    1. The user double clicks an item in the QListView to go into edit mode
    2. The user enters in invalid data into the edit widget for the item, then signals that he is done editing (by, i.e., hitting enter, or changing focus away from the edit widget, or whatever.)
    3. The application checks the data, sees that it's invalid, and displays an error dialog to the user. The edit widget is kept around and focus is returned to it when the dialog is dismissed, so that the user can continue editing his data.
    4. When the user has entered valid data, and signals that he is done editing, the application validates it, then saves the data to the model and hides the edit widget as normal.

    After mucking around in the source for QAbstractItemView and QStyledItemDelegate, I have found that this is a mess to implement. The delegate has a non-virtual eventFilter function that it uses to determine when the user has finished editing. It then sends two signals to the ItemView: The first causes the ItemView to tell the delegate to save its data to the model; the second signal causes the ItemView to destroy the edit widget.

    So I've figured I either need to somehow hook the delegates eventFilter() which detects when editing is done, and cause it to validate the data before sending the commit data & destroy widget signals; or I can hook into QAbstractItemView's setItemDelegate(), which is responsible for wiring up the slots for the commit & destroy signals, and hopefully wire those signals into my validation slots, which will then pass on the signals if the data is valid. I'd rather do the latter. But the catch is neither function is virtual!

    So how can I get this to work? Overriding the non-virtual function won't work, will it? And the only other thing I can think of is to copy&paste all 4,000+ lines of code for QAbstractItemDelegate, add the "virtual" keyword before setItemDelegate(), rename the class, and compile it into a new module. Besides being a PITA, this will also mean I lose out on updates to QAbstractItemDelegate -- so if Nokia updates it significantly in the next version of Qt, I'm out of luck.

    Is there a better way to do this?

    (I've tried validating the data in the model and, if invalid, calling ListView::edit() on the item again, but that doesn't seem to work. I can get the model to not save the data, of course, but can't find a way to let the user keep editing that data.)

  2. #2
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: Adding validation to a QListView's edit mode

    Can't you use a normal delegate and add a custom editor to it. Then after the user has finished his input, QStyledItemDelegate::setModelData() is called. There check for validity (you should also be able to display a dialog) and set the data.

  3. #3
    Join Date
    May 2010
    Posts
    10
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Adding validation to a QListView's edit mode

    The main problem with that is that setModelData() is called based (indirectly) on the commitData() signal being emitted by the delegate, which is always emitted right before closeEditor(). So I can stop the data from being written, but not the editor from being closed.

    I did discover that eventFilter() was actually virtual, so I have tried overriding that. I also hooked the editor's editingFinished signal in my createEditor() function (inspired by the Programming Qt 4 book.) It kinda works, but has some bugs.

    First, when the window is being closed with the editor open, the "input error" dialog fires like 3 times, presumably because editingFinished fires a bunch of times.

    Second, I can't get the focus to work correctly. If I hit 'enter' in the editor, the error fires and focus stays on the editor correctly, but if I try to close the editor based on it losing focus, the editor doesn't keep focus. I have editor->setFocus() called (I even tried using a queued dispatch of that signal to editor.) I have also tried swollowing the FocusOut event in the editor's eventFilter(), to no effect. The editor retains the text input cursor, but the actual focus goes to whatever was clicked. How can I change that?

  4. #4
    Join Date
    Jul 2010
    Posts
    53
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Adding validation to a QListView's edit mode

    why does you can't set your own editor which commits data(and closes) only when it's valid? reimplement delegates createEditor(...); method and create desired editors.

  5. #5
    Join Date
    May 2010
    Posts
    10
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Adding validation to a QListView's edit mode

    That's what I'm doing right now -- I have my own custom delegate which uses a QLineEdit widget as its editor, then hooks into that widget's evenFilter to tell when the user has pressed enter/esc or the widget has lost focus. It works great for keeping the widget open and not saving the data when it is invalid, but the problem is that last one: losing focus. When my widget gets a FocusOut event, I try to prevent it from losing focus, but it doesn't work.

    It also has a bug where it gets a bunch of FocusOut events when the window is closing, which causes my validation code to fire 3 times, and 3 "invalid input" error boxes to popup one after the other, right as the winow should be closing.

  6. #6
    Join Date
    Jul 2010
    Posts
    53
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Adding validation to a QListView's edit mode

    Quote Originally Posted by MattT View Post
    That's what I'm doing right now -- I have my own custom delegate which uses a QLineEdit widget as its editor, then hooks into that widget's evenFilter to tell when the user has pressed enter/esc or the widget has lost focus. It works great for keeping the widget open and not saving the data when it is invalid, but the problem is that last one: losing focus. When my widget gets a FocusOut event, I try to prevent it from losing focus, but it doesn't work.

    It also has a bug where it gets a bunch of FocusOut events when the window is closing, which causes my validation code to fire 3 times, and 3 "invalid input" error boxes to popup one after the other, right as the winow should be closing.
    i sad. your own editor. i mean subclass from QLineEdit and reimplement event filter, then send editingFinished(); signal only when your data is valid.
    and for future, read more Qt's documentation. and examples, like this.

  7. #7
    Join Date
    May 2010
    Posts
    10
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Adding validation to a QListView's edit mode

    Even if I create a widget, I still have the problem with losing focus. Creating a new widget doesn't solve the problem, it only makes my problem with delegates a problem with widgets.

    The problem isn't with not sending the edtingFinished() signal -- I have a version of my code which doesn't even use that signal, and uses an event filter on the widget to detect when the user is done editing (presses 'enter' or 'esc', or the widget loses focus) -- it's with getting my widget to retain focus, and at having the FocusOut events fire when the window is closing, causing my "invalid data" error box to pop up a bunch.

    Also, I think your link should be to here You should always check that you're using the latest version of the Qt docs. As you can see, that example has been updated to use the QStyledItemDelegate now.
    Last edited by MattT; 31st July 2010 at 00:33.

  8. #8
    Join Date
    Jul 2010
    Posts
    53
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Adding validation to a QListView's edit mode

    I have a version of my code which doesn't
    QLineEdit automatically sends this signal, read.

  9. #9
    Join Date
    May 2010
    Posts
    10
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Adding validation to a QListView's edit mode

    Yes, but it isn't hooked up to anything by default. The signals that cause the editor to close are commitData and closeEditor, emitted by the delegate. Check the code for QListView/QAbstractItemView, you'll see. I have one version of my code where I hook that signal into one of my delegate's slots in order to validate the data and then, if valid, emit commitData and closeEditor to the ListView and, if not valid, open up an error dialog. The other version of my code doesn't listen for editingFinished, and just uses the QLineEdit's event filter to try to determine when the user has pressed enter, esc or the editor has lost focus. If it does it emits commitData and closeEditor.

  10. #10
    Join Date
    Jul 2010
    Posts
    53
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Adding validation to a QListView's edit mode

    if not valid, open up an error dialog
    and do not close editor inside cell?

    you say you have 2 versions. both are not working?

  11. #11
    Join Date
    May 2010
    Posts
    10
    Thanks
    1
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Adding validation to a QListView's edit mode

    Yup, now we're on the same page.

    The problem isn't with the editor closing -- I can prevent that fine. The problem is with the editor losing focus. How do I keep focus on the editor, even when the user clicks on another widget?

Similar Threads

  1. Multiple clicks required to get into edit mode on QTreeView
    By JonInAnnArbor in forum Qt Programming
    Replies: 10
    Last Post: 26th November 2012, 18:59
  2. Delegates and edit mode while scrolling
    By Kiko in forum Qt Programming
    Replies: 0
    Last Post: 29th November 2009, 13:04
  3. Replies: 8
    Last Post: 23rd October 2009, 15:33
  4. QListView 'details' mode
    By squidge in forum Qt Programming
    Replies: 1
    Last Post: 7th October 2009, 07:55
  5. Adding a line edit in a toolbar
    By borges in forum Qt Tools
    Replies: 1
    Last Post: 16th August 2007, 15:33

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.