PDA

View Full Version : Reusing the editing widget with QtItemDelegate



bcollie
31st May 2010, 16:52
Is there a way to prevent the view from destroying the widget returned from QItemDelegate::createEditor() ?
I would like to reuse this widget in subsequent calls if possible.

Thanks
Bruce

tbscope
31st May 2010, 19:09
I guess you need to create a subclassed item delegate and reimplement the createEditor function.

Why do you want to reuse the widget?

bcollie
1st June 2010, 09:44
I have created a subclass of QItemDelegate that returns a widget from createEditor, but this widget is destroyed when the in cell editing has completed.

My reason for wanting to retain and reuse the widget is to do with the application framework that we use, it would be much easier to reuse the widget, than having to recreate it all the time. Also the user is likely to do a lot of in cell editing within this application, so reuse makes sense.

aamer4yu
1st June 2010, 11:18
But at a time you will be editing only a single cell, right ?
So using a editor till you are editing, and then destroying it makes sense. What if the user never enters the edit mode ?

Still if you want to use a permanent widget for editor, you can create a singleton of the editor widget, and return instance of this widget from within the createEditor .

bcollie
1st June 2010, 11:39
Please explain (sample code?) how a singleton would prevent the deletion of the widget by the view?

I have just found one way to circumvent the destruction, by installing an event filter on the widget and rejecting QEvent DeferredDelete

tbscope
1st June 2010, 11:44
Please explain (sample code?) how a singleton would prevent the deletion of the widget by the view?
You keep a list of editors in your subclassed delegate (for each item or cell). When the widget already exists return the existing one, if not, create a new one.


I have just found one way to circumvent the destruction, by installing an event filter on the widget and rejecting QEvent DeferredDelete
This maybe stops the deleting, but it doesn't stop the delegate from returning a new widget.

bcollie
1st June 2010, 12:15
Ok I must be missing something here, from the example code I have, any widget returned from createEditor will be destroyed by the view once the in cell editing has finished, so retaining a reference to the widget within the delegate will end up returning a bad pointer the next time createEditor is called.

Adding the event filter is the only way I have found to prevent this.

tbscope
1st June 2010, 12:29
Yes, you'll need to prevent the deletion.
If this needs to be done with an event, I don't know.

One thing to do is look at the source code of QItemDelegate. This can be complex.
Therefor, it might be better to start with an abstract item delegate, then you have a lot more control (as in: less code to change).

SixDegrees
1st June 2010, 12:41
In general, trying to do end runs around complex systems of objects - like Qt's Model/View/Delegate system - is a bad idea. Yes, you can probably find a solution. But your code will be significantly more complex and difficult to maintain than otherwise.

Creating/deleting delegates is a reasonable time/memory tradeoff in nearly all cases. Consider that each and every cell in a table can potentially contain its own custom delegate; now, you potentially have thousands of delegate objects slumming around, with only one of them ever active at any given time - a huge waste of memory. Meanwhile, creation/deletion of a specialized delegate is not typically going to require much overhead, and it keeps as much memory freed up as possible.

Unless your delegate creation takes a significant amount of time, I'd work within Qt's framework and just allow your delegate to be created and deleted by the view.

If you really can't do this, you're going to have to add some sort of smart pointer with reference counting to your singleton and overload the delete() operator. Note that this sort of thing, while feasible, gets very tricky very quickly.

aamer4yu
1st June 2010, 14:52
I have just found one way to circumvent the destruction, by installing an event filter on the widget and rejecting QEvent DeferredDelete
Yeps.. sorry I forgot about the deletion case..

but I guess you can try the following - am not sure if its a good solution.

in createEditor() emit a signal(editingRequired()) that editing widget needs to be displayed. Return 0 from this function.
connect editingRequired() to some slot of your delegate... pass some info if required about where to show the editor, etc.
Now in the slot for editingRequired() ,you can use the singleton concept.

Since you return 0 from createEditor deletion wont be called.. and still you have a way to use the singleton.


Still I would suggest let it be the way it is, dont think creating / deleting editors are that heavy. Give it a try though :)