QItemDelegate not getting called



  • NOTE: While I'm using PyQt for this project, I believe this question is not specific to PyQt, which is why I posted it here instead of in the Language Bindings forum. I'm actually more fluent in C++ than Python, so answers in either language will be fine and appreciated. If I was wrong in choosing this form, please move it. Thank you.

    I'm working on a project for acquainting myself with Qt5 and PyQt5. The model is functioning and based on QAbstractTableModel. I have both a QTableView and a QDataWidgetMapper set to the same model. The QDataWidgetMapper is handling a handful of widgets that handle the display of the selected row from the model and are used for editing rows in the model. The QTableView is read-only and mainly used for selection of the current model row, however it also displays some columns from the model.
    @self.tableviewOperations.setModel(model_operations)
    self.tableviewOperations.setItemDelegate(DelegateTableOperations(self))
    mapper_operations = QDataWidgetMapper(self)
    mapper_operations.setModel(model_operations)
    mapper_operations.setItemDelegate(DelegateMapperOperations(self))@
    I use a delegate based on QItemDelegate to handle the widgets via setEditorData() and setModelData() and set as the item delegate for the QDataWidgetMapper. This delegate works properly. I have a second delegate that is purely used for QTableView display. setEditorData() for this delegate never gets called.
    @class DelegateTableOperations(QItemDelegate):
    def init(self, parent=None):
    super(QItemDelegate, self).init(parent)
    def setEditorData(self, editor, index):
    # operate on editor here or call default delegate:
    QItemDelegate.setEditorData(self, editor, index)

    class DelegateMapperOperations(QItemDelegate):
    def init(self, parent=None):
    super(QItemDelegate, self).init(parent)
    def setEditorData(self, editor, index):
    # operate on editor here or call default delegate:
    QItemDelegate.setEditorData(self, editor, index)
    def setModelData(self, editor, model, index):
    # operate on model here depending on index or call default delegate:
    QItemDelegate.setModelData(self, editor, model, index)@
    I also tried using setItemDelegateForColumn() but that did not help.

    I realize that I could modify the text to be displayed directly from the data() function in the model for the DisplayRole role, but that complicates the display of the data for the QComboBoxes controlled by QDataWidgetMapper. The table and combobox display slightly different text for some columns so I'd rather handle the differences at the delegate rather than in the model (which is also more appropriate since it keeps view handling the in view).

    Why does my item delegate for the QDataWidgetMapper work perfectly, but the item delegate attached directly to the QTableView get ignored?



  • Ensure that you have correct signature of the functions implemented in delegate.

    Quick check you can do in C++.

    @ QMyDelegate *myDelegate = new QMyDelegate();
    tableView->setItemDelegateForColumn(1,myDelegate);
    @

    @class QMyDelegate : public QStyledItemDelegate
    {
    public:
    QMyDelegate();

    protected :
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    };
    @

    @QWidget* QMyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
    qDebug() << "CreateEditor " << parent->objectName() << " Index = " << index.row() << " Col = " << index.column();
    QSpinBox *box = new QSpinBox(parent);
    box->setRange(100,200);
    box->singleStep();
    return box;
    }
    @



  • Thank you for the reply. I checked my function signatures and they were correct, however, this put me onto a track.

    I modified the model to make all cells ItemIsEditable. I then double-clicked on a cell in one of the columns in question. setEditorData() was called.

    So this leads me to believe the way I am going about this is wrong. I believe I'm unsuccessfully trying to bend a mechanism designed for editing model items into tweaking the output of what is intended to be a display-only table cell.

    Let me explain my purpose, and then perhaps I can be guided to a more appropriate solution. My model's data() function returns an enum when the role is DisplayRole, instead of the text to be displayed. I'm doing it this way because two widgets (one display-only QLineEdit in the table and one model-editing QComboBox) display a textual representation of the data, but not the same text. So my plan was to return an enum from data() and then handle the widget-specific formatting of the enum into a string in the QItemDelegate. Right now, the delegate for the QComboBox handles this situation perfectly. It receives the enum from the data() call and presents the appropriate text in the QComboBox. But this doesn't seem to work for the QTableView.

    Perhaps I just need to manually emit an appropriate signal?

    If this is not doable, by what means would it best be accomplished? I can think of several workarounds that will do the job fine, but they seem awfully hacky and I'm trying to learn to use Qt per standard practices.



  • bq. Right now, the delegate for the QComboBox handles this situation perfectly.
    It receives the enum from the data() call and presents the appropriate text in the QComboBox. But this doesn’t seem to work for the QTableView

    @What do you mean here ? When you set the delegate for TableView this does not work ?

    Do you have two delegates ?

    Can you pasted your delegate code somewhere ?@



  • Yes, I'm using two delegates. One is DelegateMapperOperations which is for the QDataWidgetMapper which handles the QComboBox (working properly). The other is DelegateTableOperations for the QTreeView. I actually pasted skeleton PyQt code for the two delegates in my original post. The actual handling of the indices and calls on the model and editors shouldn't really be relevant so I left that out where the comments are. I also included the two setItemDelegate() calls in my sample code above the delegates.

    Unfortunately, while I'm fluent with C++ and can understand any code presented to me, I'm very new to Qt and I have not yet worked with Qt in C++ at all so it would be problematic for me to rewrite this specific case in C++. I could rewrite it as pseudocode if that would help. But perhaps it would be best if I take this to the Language Bindings forum after all. I had just thought this was a language agnostic problem.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.