📜 ⬆️ ⬇️

Qt Dungeons: Monster Cooking Recipes (Part 1: Editing Heterogeneous Data)

image

Every professional application developer using Qt quite often has to use the model / delegate / view bundle for various data manipulations. The main details of this template are well described in the standard guide on this topic, however, often you have to face the situation when the standard behavior needs to be expanded or supplemented for specific needs. Usually, here begins what we all love programming - a trip to our favorite scooters and rickshaws - we come up with our own solution. It was at that moment that the inner voice should have stopped us, but we cleverly parried: “I’ve already watched, there is a lot of documentation - it’s been reading for a long time, deadlines are tight and there are a lot of other things to do. And most importantly, it is not clear where to start looking. ” That is why any self-respecting developer should have on hand personally collected and tested recipes and try to replenish his collection.

Formulation of the problem


Create a draft of a simple disparate data editor based on QAbstractTableModel and add a custom type of evilType (yes, this type requires additional tweaks).

As a rule, this problem has two solutions:
')
  1. Override the createEditor function of QAbstractItemDelegate or its derivatives
  2. Add your own editor for a custom type and override the standard QDefaultItemEditorFactory factory editors

The disadvantages of the first approach are that if we have several types and delegates to them, which, as a rule, is in the case of a slightly complicated program, then you need to duplicate the createEditor code for different delegates.

The disadvantages of the second approach - redefining the standard editors factory leads to the loss of the QDefaultItemEditorFactory factory and, accordingly, the need to re-register the standard editors in our factory.

Our scooter


A hybrid class that contains a standard factory and overrides createEditor for custom types.

Code
void overrideEditorFactory(void) { class OverridenEditorFactory : public QItemEditorFactory { public: explicit OverridenEditorFactory(const QItemEditorFactory* dFactory) : _dFactory(dFactory) { auto creator = new QStandardItemEditorCreator<EvilTypeEditor>(); const auto evilTypeID = QVariant::fromValue(evilType()).userType(); registerEditor(evilTypeID, creator); } QWidget* createEditor(int userType, QWidget *parent) const { const auto evilTypeID = QVariant::fromValue(evilType()).userType(); if(evilTypeID == userType) { return QItemEditorFactory::createEditor(userType, parent); } return _dFactory->createEditor(userType, parent); } private: const QItemEditorFactory* _dFactory; }; QItemEditorFactory::setDefaultFactory(new OverridenEditorFactory(QItemEditorFactory::defaultFactory())); } 


Thus, before use, you must call the function overriding the standard factory. And now the user type will be edited everywhere according to our wishes.

Conclusion


The code is mainly illustrative, so some points can be improved. but the main approach - the minimalism of the code and the ease of scaling to multiple displays when using different delegates is preserved.

Full project code on github .

Source: https://habr.com/ru/post/276419/


All Articles