Sincerely,
Wieland J.
I found that it kind of sucks using an QAbstractItemModel. So I'm now using a QStandardItemModel which is AWESOME.
Qt Code:
'''The StandardAssetItem represents a row/column cell in the Qt model. ''' SUPPORTED_ROLES = [ Qt.EditRole, Qt.DisplayRole, Qt.CheckStateRole ] def __init__(self, mydata): self._mydata = mydata if type(mydata) == types.BooleanType: checkstate = Qt.Unchecked if mydata == True: checkstate = Qt.Checked self.setCheckState(checkstate) self.setCheckable(True) self.setEditable(False) elif type(mydata) == types.StringType: self.setText(mydata) else: self.setEditable(False) def setData(self, variant, role): if role not in self.SUPPORTED_ROLES: value = None if role in [ Qt.EditRole, Qt.DisplayRole ]: value = variant.toPyObject() # convert it to a std string. value = str(value) elif role == Qt.CheckStateRole: checkstate, okay = variant.toInt() value = checkstate == Qt.Checked if self._mydata != value: self._mydata = value # and tell the world the value changed To copy to clipboard, switch view to plain text mode
Then in your subclass of the standard item model you use this item instead of QModelIndexes (you dont need to subclass StandardItem, but it might be useful to do)
Hey I don't follow you here, I don't know python and can't understand what your code does or which methods you're over-riding. I assume you got your table view to accept a single click ? that's what I want to do with my view too. Can you please expand on what you've done ?
I'm just subclassing QStandardItem and passing in a value in the constructor. Then based on the type of the value it either builds a check box or a normal QTreeView cell.
Now of course you dont need to subclass QStandardItem, you can just check if your value is a boolean call:
Qt Code:
// for boolean values int checkstate = Qt::Unchecked; if mydata == true checkstate = Qt::Checked; item->setCheckState(checkstate); item->setCheckable(true); item->setEditable(false);To copy to clipboard, switch view to plain text mode
(that code might not be absolutely correct, I just wanted to make sure you could understand the C++ version of what I'm doing_
In my code I'm actually passing in a pointer to my object, and when setData on the QStandardItem is called I also update my object.... that way my object and the model are sync'd up without having to write my own model from scratch using a QAbstractItemModel. This works pretty well for me since I'm not to worried about the hierarchy of my model changing or things getting reordered outside of the view. If you need to worry about that then you might rethink things or at the very least implement a subject-observer to detect changes
Hi ...
So, if we could go back to combo boxes for a second, how many clicks on a view item does your program need to open a combo box ? One or more .. ?
Thanks.
You can do it with one click. I implemented my own method which uses a custom delegate and re-implements the editorEvent(). The following code is for a check box, but it wouldn't be much diferent for any other type of widget.
Qt Code:
// Trap the mouse button in editorEvent and check/uncheck the checkbox by calling setData() // which is a subclassed member of the model this delegate is attached to. QAbstractItemModel * model, { { bool checkState = index.model()->data(index, Qt::CheckStateRole).toBool(); model->setData(index, !checkState); } return true; // Event has been handled here. }To copy to clipboard, switch view to plain text mode
Hmm. Well for a check box it's easy. You are just toggling the state based on the mouse release event. But for a combobox you have to populate the combo and then actually care about which one was selected. Which all needs to happen though more events. I guess, because of the complexity, that's why the standard way of implementing the delegate is through the createEditor(), setEditorData(), setModelData() paradigm.
I'd be interested to see an example if you have one ....
for a combobox you can make a real QComboBox for each item, but set WA_DontShowOnScreen, and instead of this render it in delegate's paint method using QWidget::render() (you have to set the eventFilter on every widget so you can react on PaintEvents). Then enable mouseTracking in the view (or it's viewport - dont remember) and handle mouse movement and clicks in editorEvent().
I would like to be a "Guru"
Useful hints (try them before asking):
- Use Qt Assistant
- Search the forum
If you haven't found solution yet then create new topic with smart question.
You don't have to make a real combo box, it is populated in createEditor() method and don't forget, it's data is already set. All that has to be done is in the editorEvent() method, just call showPopup(). (I haven't tested but it should be this easy).
Last edited by vieraci; 7th July 2009 at 00:57. Reason: updated contents
Hi...
I think that my question isn't out of argument from the others, so I post here.
I have to obtain a result similar to that in the attached photo.
I started from different Qt examples in order to test different ways to obtain some results and then put them together.
At the moment I'm a bit stuck on a problem (the first): how to present data from the model in a frame like the one on the right of the sample photo. I tried to modify the spinboxdelegate example to visualize/edit/modify the data from the table in a lateral frame, but with no succes, because I don't know how to place the widget created by
QWidget *SpinBoxDelegate::createEditor function. I tried to reimplement the paint method, but the problem is always the same...
The 2nd problem is: I'm reading a lot of documentation trying to comprehend if delegates are the best solution to achieve my goal. At the moment I think so... But if someone has got much experience in this kind of programming and can indicate me an eventually better way, I'll surely evaluate it.
Note: At the moment I'm stuck on the first problem... The second is a little bigger, but It is part of the evaluation process.
I really hope someone can help me!
Best regards and Thanks in advance for your help.
Alex
Any help?
Now I tried another way to obtain my goal.
I started from a little and simple example of the treemodel and I created a model containing items from a file. As item I used QStandardItem, as model I used QStandardItemModel, and I visualized all in a QTreeView. I stored in the various Items different kind of data: an icon with DecorationRole, a string with DisplayRole and some custom data with UserRole. Now my problem is:
the data that I want to edit when I doubleclick an item are stored in UserRole because if I store them with EditRole they become the same as DisplayRole ('cause of the standard implementation of QStandardItem).
My questions are:
1. How can I edit data in UserRole?
2. If that is not possible, I suppose I have to subclass QStandardItem and reimplement data and setData methods... Is it possible to reimplement only this two methods to obtain a different behaviour for DisplayRole and EditRole? Could someone please post an example?
3. Any hints on how to edit data? I think a custom delegate would be the better way, do you?
Thanks,
Alex
You have to make your model aware of that role. So you have to make it store it somewhere and return data for it when asked from within the data() method. You also need to modify the flags returned by the model for items you wish checkable so that they return ItemIsUserCheckable.
Bookmarks