MattT
25th July 2010, 12:21
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:
The user double clicks an item in the QListView to go into edit mode
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.)
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.
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.)
The user workflow I envision for it is:
The user double clicks an item in the QListView to go into edit mode
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.)
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.
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.)