Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QItemEditorCreatorBase with custom enum
QtWS25 Last Chance

QItemEditorCreatorBase with custom enum

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 458 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    InTheBeninging
    wrote on 11 Aug 2023, 11:28 last edited by InTheBeninging 8 Nov 2023, 11:48
    #1

    Can someone give me a working example how to build a custom editor factory for a QComboBox with a custom enum as data? I tried following this example, but It won't work.
    My Code Looks like this:

    //hpp
    Q_DECLARE_METATYPE(EnumType)
    
    class EnumTypeComboBox : public QComboBox {
        Q_OBJECT
        Q_ENUM(EnumType)
        Q_PROPERTY(EnumType enumType READ enumType WRITE setEnumType USER true)
    public:
        EnumTypeComboBox (QWidget *widget = nullptr);
        EnumType enumType() const;
        void setEnumType (const EnumType &enumType);
    private:
        void populateList();
    };
    
    //cpp
    EnumTypeComboBox::EnumTypeComboBox (QWidget *widget) : QComboBox(widget) {
        populateList();
    }
    
    EnumType EnumTypeComboBox::enumType() const {
        return qvariant_cast<EnumType>(itemData(currentIndex(), qMetaTypeId<EnumType>()));
    }
    
    void EnumTypeComboBox::setEnumType(const EnumType &enumType) {
        setCurrentIndex(findData(enumType, qMetaTypeId<EnumType>()));
    }
    
    void EnumTypeComboBox::populateList() {
        addItem("First Type",EnumType::FirstType);
    }
    
    //registration
    QItemEditorFactory * factory = new QItemEditorFactory;
    
    QItemEditorCreatorBase * enumTypeCreator=
        new QStandardItemEditorCreator<EnumTypeComboBox>();
    
    factory->registerEditor(qMetaTypeId<EnumType>(), enumTypeCreator);
    
    QItemEditorFactory::setDefaultFactory(factory);
    

    It gives me 4 of these Linker Errors:
    editorwidget.obj:-1: Fehler: LNK2001: Nicht aufgelöstes externes Symbol ""public: static struct QMetaObject const EnumTypeComboBox::staticMetaObject" (?staticMetaObject@EnumTypeComboBox@@2UQMetaObject@@B)".

    Things that are not clear to me:
    The enum is included from a seperate header file. Can I even use it as Q_ENUM in my own class? Doesn't it say it adds the enum to a qmetatype automatically? Doing so results in the C:\Qt\5.15.2\msvc2019\include\QtCore\qmetatype.h:1916: Fehler: C2338: Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system Error.

    C A 2 Replies Last reply 11 Aug 2023, 11:39
    0
    • I Offline
      I Offline
      InTheBeninging
      wrote on 16 Aug 2023, 08:10 last edited by InTheBeninging
      #10

      Ok it works now. It just needed some changes.
      I had to change the property function to save the data with the Qt::UserRole. I guess because the QComboBox::addItem(QString text, QVariant userData) function used to populate the box uses the Qt::UserRole by default.

      cv::ThresholdTypes CVThresholdTypeComboBox::threshType() const {
          return qvariant_cast<cv::ThresholdTypes>(itemData(currentIndex(), Qt::UserRole));
      }
      
      void CVThresholdTypeComboBox::setThreshType(const cv::ThresholdTypes &threshType) {
          setCurrentIndex(findData(threshType, Qt::UserRole));
      }
      

      The conversion function to get a string representation of my custom metatype looks as follows.

      QString CVThresholdTypeComboBox::thresholdToString(const cv::ThresholdTypes &threshType) {
          switch(threshType) {
          case cv::THRESH_BINARY:     return "Binary";
          case cv::THRESH_BINARY_INV: return "Binary Inverted";
          case cv::THRESH_TRUNC:      return "Truncated";
          case cv::THRESH_TOZERO:     return "To Zero";
          case cv::THRESH_TOZERO_INV: return "To Zero Inverted";
          case cv::THRESH_MASK:       return "Mask";
          case cv::THRESH_OTSU:       return "Otsu";
          case cv::THRESH_TRIANGLE:   return "Triangle";
          default:                    return "Default";
          }
      }
      

      The conversion function is registered with this function.

      QMetaType::registerConverter<cv::ThresholdTypes, QString>(&CVThresholdTypeComboBox::thresholdToString);
      
      A 1 Reply Last reply 16 Aug 2023, 10:37
      0
      • I InTheBeninging
        11 Aug 2023, 11:28

        Can someone give me a working example how to build a custom editor factory for a QComboBox with a custom enum as data? I tried following this example, but It won't work.
        My Code Looks like this:

        //hpp
        Q_DECLARE_METATYPE(EnumType)
        
        class EnumTypeComboBox : public QComboBox {
            Q_OBJECT
            Q_ENUM(EnumType)
            Q_PROPERTY(EnumType enumType READ enumType WRITE setEnumType USER true)
        public:
            EnumTypeComboBox (QWidget *widget = nullptr);
            EnumType enumType() const;
            void setEnumType (const EnumType &enumType);
        private:
            void populateList();
        };
        
        //cpp
        EnumTypeComboBox::EnumTypeComboBox (QWidget *widget) : QComboBox(widget) {
            populateList();
        }
        
        EnumType EnumTypeComboBox::enumType() const {
            return qvariant_cast<EnumType>(itemData(currentIndex(), qMetaTypeId<EnumType>()));
        }
        
        void EnumTypeComboBox::setEnumType(const EnumType &enumType) {
            setCurrentIndex(findData(enumType, qMetaTypeId<EnumType>()));
        }
        
        void EnumTypeComboBox::populateList() {
            addItem("First Type",EnumType::FirstType);
        }
        
        //registration
        QItemEditorFactory * factory = new QItemEditorFactory;
        
        QItemEditorCreatorBase * enumTypeCreator=
            new QStandardItemEditorCreator<EnumTypeComboBox>();
        
        factory->registerEditor(qMetaTypeId<EnumType>(), enumTypeCreator);
        
        QItemEditorFactory::setDefaultFactory(factory);
        

        It gives me 4 of these Linker Errors:
        editorwidget.obj:-1: Fehler: LNK2001: Nicht aufgelöstes externes Symbol ""public: static struct QMetaObject const EnumTypeComboBox::staticMetaObject" (?staticMetaObject@EnumTypeComboBox@@2UQMetaObject@@B)".

        Things that are not clear to me:
        The enum is included from a seperate header file. Can I even use it as Q_ENUM in my own class? Doesn't it say it adds the enum to a qmetatype automatically? Doing so results in the C:\Qt\5.15.2\msvc2019\include\QtCore\qmetatype.h:1916: Fehler: C2338: Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system Error.

        C Offline
        C Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on 11 Aug 2023, 11:39 last edited by Christian Ehrlicher 8 Nov 2023, 11:39
        #2

        @InTheBeninging said in QItemEditorCreatorBase with custom enum:

        CVThresholdTypeComboBox

        This can not come from the class you are showing above...

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        I 1 Reply Last reply 11 Aug 2023, 11:42
        1
        • C Christian Ehrlicher
          11 Aug 2023, 11:39

          @InTheBeninging said in QItemEditorCreatorBase with custom enum:

          CVThresholdTypeComboBox

          This can not come from the class you are showing above...

          I Offline
          I Offline
          InTheBeninging
          wrote on 11 Aug 2023, 11:42 last edited by
          #3

          @Christian-Ehrlicher It is. I just forgot to change it's name :D

          C 1 Reply Last reply 11 Aug 2023, 11:54
          0
          • I InTheBeninging
            11 Aug 2023, 11:42

            @Christian-Ehrlicher It is. I just forgot to change it's name :D

            C Offline
            C Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 11 Aug 2023, 11:54 last edited by
            #4

            @InTheBeninging please post actual code. How should we know that you did not forgot or add something?
            Is the moc file beeing generated? I would guess not.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            I 1 Reply Last reply 11 Aug 2023, 12:07
            1
            • C Christian Ehrlicher
              11 Aug 2023, 11:54

              @InTheBeninging please post actual code. How should we know that you did not forgot or add something?
              Is the moc file beeing generated? I would guess not.

              I Offline
              I Offline
              InTheBeninging
              wrote on 11 Aug 2023, 12:07 last edited by InTheBeninging 8 Nov 2023, 12:17
              #5

              @Christian-Ehrlicher

              imgproc.hpp the enum from opencv

              //! type of the threshold operation
              //! ![threshold types](pics/threshold.png)
              enum ThresholdTypes {
                  THRESH_BINARY     = 0, //!< \f[\texttt{dst} (x,y) =  \fork{\texttt{maxval}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
                  THRESH_BINARY_INV = 1, //!< \f[\texttt{dst} (x,y) =  \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f]
                  THRESH_TRUNC      = 2, //!< \f[\texttt{dst} (x,y) =  \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
                  THRESH_TOZERO     = 3, //!< \f[\texttt{dst} (x,y) =  \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
                  THRESH_TOZERO_INV = 4, //!< \f[\texttt{dst} (x,y) =  \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
                  THRESH_MASK       = 7,
                  THRESH_OTSU       = 8, //!< flag, use Otsu algorithm to choose the optimal threshold value
                  THRESH_TRIANGLE   = 16 //!< flag, use Triangle algorithm to choose the optimal threshold value
              };
              

              cvthreshold.hpp

              #include <QComboBox>
              #include "opencv2/opencv.hpp"
              
              Q_DECLARE_METATYPE(cv::ThresholdTypes)
              
              class CVThresholdTypeComboBox : public QComboBox {
                  Q_OBJECT
                  Q_ENUM(cv::ThresholdTypes)
                  Q_PROPERTY(cv::ThresholdTypes threshType READ threshType WRITE setThreshType USER true)
              public:
                  CVThresholdTypeComboBox(QWidget *widget = nullptr);
                  cv::ThresholdTypes threshType() const;
                  void setThreshType(const cv::ThresholdTypes &threshType);
              private:
                  void populateList();
              };
              

              cvthreshold.cpp

              #include "cvthreshold.h"
              
              CVThresholdTypeComboBox::CVThresholdTypeComboBox(QWidget *widget) : QComboBox(widget) {
                  populateList();
              }
              
              cv::ThresholdTypes CVThresholdTypeComboBox::threshType() const {
                  return qvariant_cast<cv::ThresholdTypes>(itemData(currentIndex(), qMetaTypeId<cv::ThresholdTypes>()));
              }
              
              void CVThresholdTypeComboBox::setThreshType(const cv::ThresholdTypes &threshType) {
                  setCurrentIndex(findData(threshType, qMetaTypeId<cv::ThresholdTypes>()));
              }
              
              void CVThresholdTypeComboBox::populateList() {
                  addItem("Binary",cv::THRESH_BINARY);
                  addItem("Binary Inverted",cv::THRESH_BINARY_INV);
                  addItem("Mask",cv::THRESH_MASK);
                  addItem("Otsu",cv::THRESH_OTSU);
              }
              

              cvpipelineeditorwidget.cpp

              #include "cvpipelineeditorwidget.h"
              #include "ui_cvpipelineeditorwidget.h"
              #include <QDebug>
              #include <QComboBox>
              
              #include <QItemEditorFactory>
              #include "cvthreshold.h"
              
              CVPipelineEditorWidget::CVPipelineEditorWidget(QWidget *parent) :
                  QWidget(parent),
                  ui(new Ui::CVPipelineEditorWidget) {
                  ui->setupUi(this);
                  setAttribute(Qt::WA_DeleteOnClose);
              
                  ui->treeWidget->setHeaderLabels({"Enable","Eigenschaft","Wert"});
                  ui->treeWidget->setColumnWidth(0, 50);
              
              //TEST
                  QItemEditorFactory * factory = new QItemEditorFactory;
              
                  QItemEditorCreatorBase * threshTypeCreator =
                      new QStandardItemEditorCreator<CVThresholdTypeComboBox>();
              
                  factory->registerEditor(qMetaTypeId<cv::ThresholdTypes>(), threshTypeCreator);
              
                  QItemEditorFactory::setDefaultFactory(factory);
              //ENDTEST
              
                  QTreeWidgetItem * item = new QTreeWidgetItem(ui->treeWidget);
                  item->setCheckState(0, Qt::Checked);
                  item->setText(1, "Threshold");
                  QTreeWidgetItem * threshItem = new QTreeWidgetItem(item);
                  threshItem->setText(1, "Threshold");
                  threshItem->setData(2, Qt::DisplayRole, QStringList{"smtsmt","sad"});
                  item->addChild(threshItem);
                  QTreeWidgetItem * threshMaxItem = new QTreeWidgetItem(item);
                  threshMaxItem->setText(1, "Maximum");
                  item->addChild(threshMaxItem);
                  QTreeWidgetItem * threshTypeItem = new QTreeWidgetItem(item);
                  threshTypeItem->setText(1, "Algorithm");
                  threshTypeItem->setData(2, Qt::DisplayRole, cv::THRESH_BINARY);
                  QComboBox * threshTypeCombobox = new QComboBox;
                  threshTypeCombobox->addItem("Binary",cv::THRESH_BINARY);
                  threshTypeCombobox->addItem("Binary Inverted",cv::THRESH_BINARY_INV);
                  threshTypeCombobox->addItem("Mask",cv::THRESH_MASK);
                  threshTypeCombobox->addItem("Otsu",cv::THRESH_OTSU);
              //    ui->treeWidget->setItemWidget(threshTypeItem, 2, threshTypeCombobox);
              
                  QObject::connect(ui->treeWidget, &QTreeWidget::itemChanged, this, [this]{
                      qDebug() << "Item data changed";
                  });
              }
              

              No moc file being generated.

              C 1 Reply Last reply 11 Aug 2023, 13:48
              0
              • I InTheBeninging
                11 Aug 2023, 12:07

                @Christian-Ehrlicher

                imgproc.hpp the enum from opencv

                //! type of the threshold operation
                //! ![threshold types](pics/threshold.png)
                enum ThresholdTypes {
                    THRESH_BINARY     = 0, //!< \f[\texttt{dst} (x,y) =  \fork{\texttt{maxval}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
                    THRESH_BINARY_INV = 1, //!< \f[\texttt{dst} (x,y) =  \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f]
                    THRESH_TRUNC      = 2, //!< \f[\texttt{dst} (x,y) =  \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
                    THRESH_TOZERO     = 3, //!< \f[\texttt{dst} (x,y) =  \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f]
                    THRESH_TOZERO_INV = 4, //!< \f[\texttt{dst} (x,y) =  \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f]
                    THRESH_MASK       = 7,
                    THRESH_OTSU       = 8, //!< flag, use Otsu algorithm to choose the optimal threshold value
                    THRESH_TRIANGLE   = 16 //!< flag, use Triangle algorithm to choose the optimal threshold value
                };
                

                cvthreshold.hpp

                #include <QComboBox>
                #include "opencv2/opencv.hpp"
                
                Q_DECLARE_METATYPE(cv::ThresholdTypes)
                
                class CVThresholdTypeComboBox : public QComboBox {
                    Q_OBJECT
                    Q_ENUM(cv::ThresholdTypes)
                    Q_PROPERTY(cv::ThresholdTypes threshType READ threshType WRITE setThreshType USER true)
                public:
                    CVThresholdTypeComboBox(QWidget *widget = nullptr);
                    cv::ThresholdTypes threshType() const;
                    void setThreshType(const cv::ThresholdTypes &threshType);
                private:
                    void populateList();
                };
                

                cvthreshold.cpp

                #include "cvthreshold.h"
                
                CVThresholdTypeComboBox::CVThresholdTypeComboBox(QWidget *widget) : QComboBox(widget) {
                    populateList();
                }
                
                cv::ThresholdTypes CVThresholdTypeComboBox::threshType() const {
                    return qvariant_cast<cv::ThresholdTypes>(itemData(currentIndex(), qMetaTypeId<cv::ThresholdTypes>()));
                }
                
                void CVThresholdTypeComboBox::setThreshType(const cv::ThresholdTypes &threshType) {
                    setCurrentIndex(findData(threshType, qMetaTypeId<cv::ThresholdTypes>()));
                }
                
                void CVThresholdTypeComboBox::populateList() {
                    addItem("Binary",cv::THRESH_BINARY);
                    addItem("Binary Inverted",cv::THRESH_BINARY_INV);
                    addItem("Mask",cv::THRESH_MASK);
                    addItem("Otsu",cv::THRESH_OTSU);
                }
                

                cvpipelineeditorwidget.cpp

                #include "cvpipelineeditorwidget.h"
                #include "ui_cvpipelineeditorwidget.h"
                #include <QDebug>
                #include <QComboBox>
                
                #include <QItemEditorFactory>
                #include "cvthreshold.h"
                
                CVPipelineEditorWidget::CVPipelineEditorWidget(QWidget *parent) :
                    QWidget(parent),
                    ui(new Ui::CVPipelineEditorWidget) {
                    ui->setupUi(this);
                    setAttribute(Qt::WA_DeleteOnClose);
                
                    ui->treeWidget->setHeaderLabels({"Enable","Eigenschaft","Wert"});
                    ui->treeWidget->setColumnWidth(0, 50);
                
                //TEST
                    QItemEditorFactory * factory = new QItemEditorFactory;
                
                    QItemEditorCreatorBase * threshTypeCreator =
                        new QStandardItemEditorCreator<CVThresholdTypeComboBox>();
                
                    factory->registerEditor(qMetaTypeId<cv::ThresholdTypes>(), threshTypeCreator);
                
                    QItemEditorFactory::setDefaultFactory(factory);
                //ENDTEST
                
                    QTreeWidgetItem * item = new QTreeWidgetItem(ui->treeWidget);
                    item->setCheckState(0, Qt::Checked);
                    item->setText(1, "Threshold");
                    QTreeWidgetItem * threshItem = new QTreeWidgetItem(item);
                    threshItem->setText(1, "Threshold");
                    threshItem->setData(2, Qt::DisplayRole, QStringList{"smtsmt","sad"});
                    item->addChild(threshItem);
                    QTreeWidgetItem * threshMaxItem = new QTreeWidgetItem(item);
                    threshMaxItem->setText(1, "Maximum");
                    item->addChild(threshMaxItem);
                    QTreeWidgetItem * threshTypeItem = new QTreeWidgetItem(item);
                    threshTypeItem->setText(1, "Algorithm");
                    threshTypeItem->setData(2, Qt::DisplayRole, cv::THRESH_BINARY);
                    QComboBox * threshTypeCombobox = new QComboBox;
                    threshTypeCombobox->addItem("Binary",cv::THRESH_BINARY);
                    threshTypeCombobox->addItem("Binary Inverted",cv::THRESH_BINARY_INV);
                    threshTypeCombobox->addItem("Mask",cv::THRESH_MASK);
                    threshTypeCombobox->addItem("Otsu",cv::THRESH_OTSU);
                //    ui->treeWidget->setItemWidget(threshTypeItem, 2, threshTypeCombobox);
                
                    QObject::connect(ui->treeWidget, &QTreeWidget::itemChanged, this, [this]{
                        qDebug() << "Item data changed";
                    });
                }
                

                No moc file being generated.

                C Offline
                C Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on 11 Aug 2023, 13:48 last edited by
                #6

                @InTheBeninging said in QItemEditorCreatorBase with custom enum:

                No moc file being generated

                So what build system do you use? Without the moc file you will get this linker error

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                0
                • I InTheBeninging
                  11 Aug 2023, 11:28

                  Can someone give me a working example how to build a custom editor factory for a QComboBox with a custom enum as data? I tried following this example, but It won't work.
                  My Code Looks like this:

                  //hpp
                  Q_DECLARE_METATYPE(EnumType)
                  
                  class EnumTypeComboBox : public QComboBox {
                      Q_OBJECT
                      Q_ENUM(EnumType)
                      Q_PROPERTY(EnumType enumType READ enumType WRITE setEnumType USER true)
                  public:
                      EnumTypeComboBox (QWidget *widget = nullptr);
                      EnumType enumType() const;
                      void setEnumType (const EnumType &enumType);
                  private:
                      void populateList();
                  };
                  
                  //cpp
                  EnumTypeComboBox::EnumTypeComboBox (QWidget *widget) : QComboBox(widget) {
                      populateList();
                  }
                  
                  EnumType EnumTypeComboBox::enumType() const {
                      return qvariant_cast<EnumType>(itemData(currentIndex(), qMetaTypeId<EnumType>()));
                  }
                  
                  void EnumTypeComboBox::setEnumType(const EnumType &enumType) {
                      setCurrentIndex(findData(enumType, qMetaTypeId<EnumType>()));
                  }
                  
                  void EnumTypeComboBox::populateList() {
                      addItem("First Type",EnumType::FirstType);
                  }
                  
                  //registration
                  QItemEditorFactory * factory = new QItemEditorFactory;
                  
                  QItemEditorCreatorBase * enumTypeCreator=
                      new QStandardItemEditorCreator<EnumTypeComboBox>();
                  
                  factory->registerEditor(qMetaTypeId<EnumType>(), enumTypeCreator);
                  
                  QItemEditorFactory::setDefaultFactory(factory);
                  

                  It gives me 4 of these Linker Errors:
                  editorwidget.obj:-1: Fehler: LNK2001: Nicht aufgelöstes externes Symbol ""public: static struct QMetaObject const EnumTypeComboBox::staticMetaObject" (?staticMetaObject@EnumTypeComboBox@@2UQMetaObject@@B)".

                  Things that are not clear to me:
                  The enum is included from a seperate header file. Can I even use it as Q_ENUM in my own class? Doesn't it say it adds the enum to a qmetatype automatically? Doing so results in the C:\Qt\5.15.2\msvc2019\include\QtCore\qmetatype.h:1916: Fehler: C2338: Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system Error.

                  A Offline
                  A Offline
                  Axel Spoerl
                  Moderators
                  wrote on 12 Aug 2023, 13:19 last edited by
                  #7

                  @InTheBeninging said in QItemEditorCreatorBase with custom enum:

                  The enum is included from a seperate header file. Can I even use it as Q_ENUM in my own class?

                  That's not possible.
                  The Q_ENUM declaration has to be in the class where the enum is defined.
                  This class has to also have the Q_OBJECT macro, or (if the Q_OBJECT overhead is not needed, Q_GADGET).

                  Software Engineer
                  The Qt Company, Oslo

                  1 Reply Last reply
                  0
                  • I Offline
                    I Offline
                    InTheBeninging
                    wrote on 14 Aug 2023, 13:38 last edited by InTheBeninging
                    #8

                    Thanks for the hints @Christian-Ehrlicher and @Axel-Spoerl. I cleared my build folder before rebuilding and removed the Q_ENUM and it works now. The only problem is, that instead of showing the enums name the treewidgets cell remains empty after a selection as shown in the lower half of the image.
                    QItemEditorCreatorBase_bad.png
                    This is likely because Q_ENUM can't be used here. Is there any other way to add QString representations to custom MetaTypes?

                    A 1 Reply Last reply 14 Aug 2023, 13:43
                    0
                    • I InTheBeninging
                      14 Aug 2023, 13:38

                      Thanks for the hints @Christian-Ehrlicher and @Axel-Spoerl. I cleared my build folder before rebuilding and removed the Q_ENUM and it works now. The only problem is, that instead of showing the enums name the treewidgets cell remains empty after a selection as shown in the lower half of the image.
                      QItemEditorCreatorBase_bad.png
                      This is likely because Q_ENUM can't be used here. Is there any other way to add QString representations to custom MetaTypes?

                      A Offline
                      A Offline
                      Axel Spoerl
                      Moderators
                      wrote on 14 Aug 2023, 13:43 last edited by
                      #9

                      @InTheBeninging
                      As said already: Use the Q_OBJECT or Q_GADGETmacro. Or implement a manual conversion function.

                      Software Engineer
                      The Qt Company, Oslo

                      1 Reply Last reply
                      0
                      • I Offline
                        I Offline
                        InTheBeninging
                        wrote on 16 Aug 2023, 08:10 last edited by InTheBeninging
                        #10

                        Ok it works now. It just needed some changes.
                        I had to change the property function to save the data with the Qt::UserRole. I guess because the QComboBox::addItem(QString text, QVariant userData) function used to populate the box uses the Qt::UserRole by default.

                        cv::ThresholdTypes CVThresholdTypeComboBox::threshType() const {
                            return qvariant_cast<cv::ThresholdTypes>(itemData(currentIndex(), Qt::UserRole));
                        }
                        
                        void CVThresholdTypeComboBox::setThreshType(const cv::ThresholdTypes &threshType) {
                            setCurrentIndex(findData(threshType, Qt::UserRole));
                        }
                        

                        The conversion function to get a string representation of my custom metatype looks as follows.

                        QString CVThresholdTypeComboBox::thresholdToString(const cv::ThresholdTypes &threshType) {
                            switch(threshType) {
                            case cv::THRESH_BINARY:     return "Binary";
                            case cv::THRESH_BINARY_INV: return "Binary Inverted";
                            case cv::THRESH_TRUNC:      return "Truncated";
                            case cv::THRESH_TOZERO:     return "To Zero";
                            case cv::THRESH_TOZERO_INV: return "To Zero Inverted";
                            case cv::THRESH_MASK:       return "Mask";
                            case cv::THRESH_OTSU:       return "Otsu";
                            case cv::THRESH_TRIANGLE:   return "Triangle";
                            default:                    return "Default";
                            }
                        }
                        

                        The conversion function is registered with this function.

                        QMetaType::registerConverter<cv::ThresholdTypes, QString>(&CVThresholdTypeComboBox::thresholdToString);
                        
                        A 1 Reply Last reply 16 Aug 2023, 10:37
                        0
                        • I InTheBeninging
                          16 Aug 2023, 08:10

                          Ok it works now. It just needed some changes.
                          I had to change the property function to save the data with the Qt::UserRole. I guess because the QComboBox::addItem(QString text, QVariant userData) function used to populate the box uses the Qt::UserRole by default.

                          cv::ThresholdTypes CVThresholdTypeComboBox::threshType() const {
                              return qvariant_cast<cv::ThresholdTypes>(itemData(currentIndex(), Qt::UserRole));
                          }
                          
                          void CVThresholdTypeComboBox::setThreshType(const cv::ThresholdTypes &threshType) {
                              setCurrentIndex(findData(threshType, Qt::UserRole));
                          }
                          

                          The conversion function to get a string representation of my custom metatype looks as follows.

                          QString CVThresholdTypeComboBox::thresholdToString(const cv::ThresholdTypes &threshType) {
                              switch(threshType) {
                              case cv::THRESH_BINARY:     return "Binary";
                              case cv::THRESH_BINARY_INV: return "Binary Inverted";
                              case cv::THRESH_TRUNC:      return "Truncated";
                              case cv::THRESH_TOZERO:     return "To Zero";
                              case cv::THRESH_TOZERO_INV: return "To Zero Inverted";
                              case cv::THRESH_MASK:       return "Mask";
                              case cv::THRESH_OTSU:       return "Otsu";
                              case cv::THRESH_TRIANGLE:   return "Triangle";
                              default:                    return "Default";
                              }
                          }
                          

                          The conversion function is registered with this function.

                          QMetaType::registerConverter<cv::ThresholdTypes, QString>(&CVThresholdTypeComboBox::thresholdToString);
                          
                          A Offline
                          A Offline
                          Axel Spoerl
                          Moderators
                          wrote on 16 Aug 2023, 10:37 last edited by
                          #11

                          @InTheBeninging
                          Nice, good that you got it working.

                          Some minor beautification nits:

                          • text values could be stored in an array and the enum value be used as the index.
                          • the function could be static constexpr.
                          • in switches over enums, I don't use default. That way, the compiler rants at me, if I have (again!!) forgotten to implement new enum values.
                            Q_UNREACHABLE()can be added after the switch, but it doesn't like static constexpron some platforms.

                          Software Engineer
                          The Qt Company, Oslo

                          1 Reply Last reply
                          0
                          • I InTheBeninging has marked this topic as solved on 16 Aug 2023, 15:42

                          9/11

                          14 Aug 2023, 13:43

                          • Login

                          • Login or register to search.
                          9 out of 11
                          • First post
                            9/11
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved