Results 1 to 12 of 12

Thread: Q_DECLARE_METATYPE problem

  1. #1
    Join Date
    Mar 2010
    Location
    Auckland, NZ
    Posts
    121
    Thanks
    9
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Q_DECLARE_METATYPE problem

    I'm now building with Qt5 code that compiled with no problems with Qt4, and getting an error message that is a bit obscure to me.

    F:\Qt\5.13.0\msvc2017\include\QtCore\qmetatype.h:1 798: error: C2338: Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system
    F:\Qt\5.13.0\msvc2017\include\QtCore\qmetatype.h:1 805: see reference to function template instantiation 'int qMetaTypeId<T>(void)' being compiled
    with
    [
    T=QMouseEvent *
    ]
    D:\testing\build-vspheroid-Qt3d\release\moc_myqgraphicsview.cpp:98: see reference to function template instantiation 'int qRegisterMetaType<QMouseEvent*>(void)' being compiled
    F:\Qt\5.13.0\msvc2017\include\QtCore\qatomic.h:56: see reference to class template instantiation 'QBasicAtomicInteger<int>' being compiled
    F:\Qt\5.13.0\msvc2017\include\QtCore\qatomic.h:154 : see reference to class template instantiation 'QAtomicInteger<int>' being compiled

    I have extended QGraphicsView to allow image save on a mouse click like this:

    myqgraphicsview.h:

    Qt Code:
    1. #ifndef MYQGRAPHICSVIEW_H
    2. #define MYQGRAPHICSVIEW_H
    3.  
    4. #include <QWidget>
    5. #include <QGraphicsView>
    6. #include <QGraphicsScene>
    7. #include <QMouseEvent>
    8. #include <QFileDialog>
    9.  
    10. #include "log.h"
    11. LOG_USE();
    12.  
    13. class MyQGraphicsView : public QGraphicsView
    14. {
    15. Q_OBJECT
    16. public:
    17. explicit MyQGraphicsView(QWidget *parent = nullptr);
    18.  
    19. signals:
    20. void viewClicked();
    21. public slots:
    22. void mouseReleaseEvent(QMouseEvent * e);
    23. void saveImage();
    24. private:
    25. // member variable to store click position
    26. QPoint m_lastPoint;
    27. // member variable - flag of click beginning
    28. bool m_mouseClick;
    29. };
    30.  
    31. #endif // MYQGRAPHICSVIEW_H
    To copy to clipboard, switch view to plain text mode 

    myqgraphicsview.cpp:

    Qt Code:
    1. #include "myqgraphicsview.h"
    2.  
    3. MyQGraphicsView::MyQGraphicsView(QWidget *parent) :
    4. QGraphicsView(parent)
    5. {
    6. }
    7.  
    8. void MyQGraphicsView::mouseReleaseEvent(QMouseEvent * e)
    9. {
    10. if (e->button() == Qt::RightButton) {
    11. saveImage();
    12. }
    13. }
    14.  
    15. void MyQGraphicsView::saveImage()
    16. {
    17. QGraphicsScene *ascene = this->scene();
    18. ascene->clearSelection(); // Selections would also render to the file
    19. ascene->setSceneRect(ascene->itemsBoundingRect()); // Re-shrink the scene to it's bounding contents
    20. QImage image(ascene->sceneRect().size().toSize(), QImage::Format_ARGB32); // Create the image with the exact size of the shrunk scene
    21. image.fill(Qt::transparent); // Start all pixels transparent
    22. QPainter painter(&image);
    23. ascene->render(&painter);
    24. QString fileName = QFileDialog::getSaveFileName(this, tr("Image File Name"), ".", tr("Image Files (*.png)"));
    25. if (fileName.compare("") != 0) {
    26. image.save(fileName);
    27. }
    28. }
    To copy to clipboard, switch view to plain text mode 

    I don't know where and how I should insert the Q_DECLARE_METATYPE line. I don't know what metatype it is referring to (or even what a metatype is).

  2. #2
    Join Date
    Aug 2019
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Q_DECLARE_METATYPE problem

    I tried the code you posted and it compiles fine without any error (as expected). So to be honest I don't understand why you have this error message.

    In fact you don't have to declare Qt's types as metatypes as Qt already knows them.
    Normally you should not have to declare any metatype for overriding the mouseReleaseEvent().

    Perhaps you can try to rebuild everything from scratch, from a clean base (remove every build-generated files, check your .pro file, run qmake and then run the compilation).

    To answer your questioning about the metatypes, you need to use Q_DECLARE_METATYPE for user custom classes/structures if you want to use them in QVariant or in signals/slots connections. The related type must provide a public default constructor, a public copy constructor and a public destructor to be eligible to be declared as a metatype. Usually, we call the macro right below the class/struct declaration in the header file. If you use queued connections, you'll need to call qRegisterMetaType() too.
    For more accurate information, look at the documentation about it.

  3. #3
    Join Date
    Mar 2010
    Location
    Auckland, NZ
    Posts
    121
    Thanks
    9
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Q_DECLARE_METATYPE problem

    Thanks for looking at this. The situation now is even more confusing. I have removed MyQGraphicsView from the program, which eliminated that error. But after adding back most of the rest of the code (I started with a very stripped-down version of the program I am converting over from Qt4 to Qt5) I am getting the same Q_DECLARE_METATYPE error, but now I can't see where it is coming from. These are the 5 lines of error messages:

    F:\Qt\5.13.0\msvc2017\include\QtCore\qmetatype.h:1 798: error: C2338: Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system
    F:\Qt\5.13.0\msvc2017\include\QtCore\qmetatype.h:1 805: see reference to function template instantiation 'int qMetaTypeId<T>(void)' being compiled
    with
    [
    T=QMouseEvent *
    ]
    D:\testing\build-vspheroid-Qt3d\release\moc_mainwindow.cpp:686: see reference to function template instantiation 'int qRegisterMetaType<QMouseEvent*>(void)' being compiled
    F:\Qt\5.13.0\msvc2017\include\QtCore\qatomic.h:56: see reference to class template instantiation 'QBasicAtomicInteger<int>' being compiled
    F:\Qt\5.13.0\msvc2017\include\QtCore\qatomic.h:154 : see reference to class template instantiation 'QAtomicInteger<int>' being compiled

    The relevant code in moc_mainwindow.cpp is:
    Qt Code:
    1. case 73:
    2. switch (*reinterpret_cast<int*>(_a[1])) {
    3. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    4. case 0:
    5. *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QMouseEvent* >(); break;
    6. }
    7. break;
    To copy to clipboard, switch view to plain text mode 

    i.e. again reference to QMouseEvent. The file mainwindow.cpp is quite long, a couple of thousand lines, and I have no idea what part of the code is generating this error. There is no indication of what is causing the error. I have cleaned everything, run qmake and rebuilt (many times).

    Edit: I have discovered that the error is triggered by this function:

    Qt Code:
    1. void MainWindow::clickedGraph(QMouseEvent *event)
    2. {
    3. if (event->button() == Qt::RightButton) {
    4. LOG_QMSG("Right button click");
    5. QString fileName = QFileDialog::getSaveFileName(this, tr("Select image file"), ".",
    6. tr("Image files (*.png)"));
    7. if (fileName.compare("") == 0) {
    8. return;
    9. }
    10. colony_plot->savePng(fileName);
    11. }
    12. }
    To copy to clipboard, switch view to plain text mode 

    specifically, it appears, by the function argument. There doesn't seem to be anything unusual about this.
    Last edited by gib; 19th August 2019 at 13:48.

  4. #4
    Join Date
    Aug 2019
    Posts
    7
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Q_DECLARE_METATYPE problem

    It seems strange indeed.

    When you "cleaned everything", did you also remove the moc files ? (in order to let qmake regenerate them properly).

    If this problem still appears, I think it comes either from the way you do the porting from Qt4 to Qt5 or from some code that becomes wrong from a version to another by generating side effects (which makes it harder to track).
    I do not pretend it is the case but if we could have a complete, minimal, reproducible (compilable and runnable) example that illustrates your problem, it would be much better to find the problem (and this way, we will avoid uncertain conjectures).

  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Q_DECLARE_METATYPE problem

    Any errors from Qt's metatype systems are usually due to MOC (the "meta-object compiler"), which reads your header files and generates a "moc" file with metatype information for every class where the Q_OBJECT macro is declared.

    If, in doing your porting, you are simply copying over moc_*.cpp and ui_*.h files, then this is incorrect. These files are generated during the build process from the corresponding *.h and *.ui files by the MOC and UIC programs. You should remove them then rebuild the whole thing so they can be regenerated against the proper set of Qt 5 headers and libraries.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  6. #6
    Join Date
    Mar 2010
    Location
    Auckland, NZ
    Posts
    121
    Thanks
    9
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Q_DECLARE_METATYPE problem

    No, I started with just the source files, certainly no moc_ files and no ui_*.h files. I'm on the trail of the bug again this morning.

    Edit: If I comment out clickedGraph I can build a working version of the program (not yet complete, but displaying the UI). If I comment out just the contents of the function, so I have just:

    void MainWindow::clickedGraph(QMouseEvent *event)
    {
    }

    I get the metatype error.

    There is something very odd about this line:

    void MainWindow::clickedGraph(QMouseEvent *event)

    In Qt Creator 'MainWindow' normally shows as pink, the rest of the line a dark blue. On this line 'inWindow::cl' was pink, the rest dark blue. I made a copy of the line (commenting out the original line), and this showed all as dark blue. After a couple of cycles of commenting and uncommenting, the anomalous pink disappeared, now what I see is either:

    Qt Code:
    1. //void MainWindow::clickedGraph(QMouseEvent *event)
    2. void MainWindow::clickedGraph(QMouseEvent *event)
    To copy to clipboard, switch view to plain text mode 

    or
    Qt Code:
    1. void MainWindow::clickedGraph(QMouseEvent *event)
    2. //void MainWindow::clickedGraph(QMouseEvent *event)
    To copy to clipboard, switch view to plain text mode 

    In the first case, the uncommented line is all black, while in the second case it is all dark blue (I don't know if these colours show up here.)

    Oh, now after some commenting and uncommenting, the uncommented line is all black in both cases. So I have a moving target, and I don't even know what it is.
    It is looking increasingly like bad behaviour on the part of Qt Creator.
    Last edited by gib; 20th August 2019 at 00:54.

  7. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Q_DECLARE_METATYPE problem

    Then are you running qmake after adding new files to the project? Qmake is necessary in order to ensure that the moc_*.cpp and ui*.h files are added to the project when you add new source files.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  8. #8
    Join Date
    Mar 2010
    Location
    Auckland, NZ
    Posts
    121
    Thanks
    9
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Q_DECLARE_METATYPE problem

    Yes, I always run qmake after a clean I also manually deleted the contents of the build directory.


    Added after 12 minutes:


    The part of the error message that refers to moc_mainwindow.cpp:

    D:\testing\build-vspheroid-Qt3d\release\moc_mainwindow.cpp:677: see reference to function template instantiation 'int qRegisterMetaType<QMouseEvent*>(void)' being compiled

    gives the line number that corresponds to the third-to-last line in this chunk of code:

    Qt Code:
    1. case 71: _t->clickedGraph((*reinterpret_cast< QMouseEvent*(*)>(_a[1]))); break;
    2. case 72: _t->on_cbox_SAVE_PROFILE_DATA_toggled((*reinterpret_cast< bool(*)>(_a[1]))); break;
    3. case 73: _t->on_cbox_SAVE_SLICE_DATA_toggled((*reinterpret_cast< bool(*)>(_a[1]))); break;
    4. case 74: _t->on_cbox_SAVE_FACS_DATA_toggled((*reinterpret_cast< bool(*)>(_a[1]))); break;
    5. case 75: _t->buttonClick_cell_constituent((*reinterpret_cast< QAbstractButton*(*)>(_a[1]))); break;
    6. case 76: _t->buttonClick_field_constituent((*reinterpret_cast< QAbstractButton*(*)>(_a[1]))); break;
    7. case 77: _t->buttonClick_plane((*reinterpret_cast< QAbstractButton*(*)>(_a[1]))); break;
    8. case 78: _t->buttonClick_canvas((*reinterpret_cast< QAbstractButton*(*)>(_a[1]))); break;
    9. case 79: _t->textChanged_fraction((*reinterpret_cast< QString(*)>(_a[1]))); break;
    10. case 80: _t->textEdited_fraction((*reinterpret_cast< QString(*)>(_a[1]))); break;
    11. case 81: _t->sc_textEdited((*reinterpret_cast< QString(*)>(_a[1]))); break;
    12. case 82: _t->onSelectCellConstituent(); break;
    13. case 83: _t->onSelectFieldConstituent(); break;
    14. case 84: _t->setColourScheme((*reinterpret_cast< int(*)>(_a[1]))); break;
    15. case 85: _t->showColours((*reinterpret_cast< int(*)>(_a[1]))); break;
    16. case 86: _t->on_pushButton_update_FACS_Histo_clicked(); break;
    17. case 87: _t->on_pushButton_saveHisto_clicked(); break;
    18. case 88: _t->on_pushButton_saveFACS_clicked(); break;
    19. case 89: _t->showSummary((*reinterpret_cast< int(*)>(_a[1]))); break;
    20. case 90: _t->updateProfilePlots(); break;
    21. case 91: _t->showFACS(); break;
    22. case 92: _t->showHisto(); break;
    23. case 93: _t->saveFACSImage(); break;
    24. case 94: _t->saveHistoImage((*reinterpret_cast< bool(*)>(_a[1]))); break;
    25. case 95: _t->saveHistoData((*reinterpret_cast< QString(*)>(_a[1]))); break;
    26. case 96: _t->processGroupBoxClick((*reinterpret_cast< QString(*)>(_a[1]))); break;
    27. case 97: _t->createFACSPage(); break;
    28. case 98: _t->test_histo(); break;
    29. case 99: _t->makeHistoPlot((*reinterpret_cast< int(*)>(_a[1])),(*reinterpret_cast< double(*)>(_a[2])),(*reinterpret_cast< double(*)>(_a[3])),(*reinterpret_cast< QVector<double>(*)>(_a[4])),(*reinterpret_cast< QString(*)>(_a[5]))); break;
    30. case 100: _t->pauseServer(); break;
    31. case 101: _t->stopServer(); break;
    32. case 102: { int _r = _t->main3d((*reinterpret_cast< QWidget*(*)>(_a[1])));
    33. if (_a[0]) *reinterpret_cast< int*>(_a[0]) = std::move(_r); } break;
    34. case 103: _t->mover((*reinterpret_cast< QVector3D(*)>(_a[1]))); break;
    35. case 104: _t->runMover(); break;
    36. case 105: _t->start_runMover(); break;
    37. case 106: _t->initialiseSteps(); break;
    38. default: ;
    39. }
    40. } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
    41. switch (_id) {
    42. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    43. case 11:
    44. switch (*reinterpret_cast<int*>(_a[1])) {
    45. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    46. case 0:
    47. *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QTableWidget* >(); break;
    48. }
    49. break;
    50. case 12:
    51. switch (*reinterpret_cast<int*>(_a[1])) {
    52. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    53. case 0:
    54. *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QTableWidget* >(); break;
    55. }
    56. break;
    57. case 31:
    58. switch (*reinterpret_cast<int*>(_a[1])) {
    59. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    60. case 0:
    61. *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QAbstractButton* >(); break;
    62. }
    63. break;
    64. case 39:
    65. switch (*reinterpret_cast<int*>(_a[1])) {
    66. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    67. case 0:
    68. *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QRadioButton* >(); break;
    69. }
    70. break;
    71. case 63:
    72. switch (*reinterpret_cast<int*>(_a[1])) {
    73. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    74. case 0:
    75. *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QAbstractButton* >(); break;
    76. }
    77. break;
    78. case 64:
    79. switch (*reinterpret_cast<int*>(_a[1])) {
    80. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    81. case 0:
    82. *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QAbstractButton* >(); break;
    83. }
    84. break;
    85. case 65:
    86. switch (*reinterpret_cast<int*>(_a[1])) {
    87. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    88. case 0:
    89. *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QAbstractButton* >(); break;
    90. }
    91. break;
    92. case 71:
    93. switch (*reinterpret_cast<int*>(_a[1])) {
    94. default: *reinterpret_cast<int*>(_a[0]) = -1; break;
    95. case 0:
    96. *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QMouseEvent* >(); break;
    97. }
    98. break;
    To copy to clipboard, switch view to plain text mode 

    Note that case 71 at the start of this extract refers to clickedGraph.
    It seems crazy that this could be related to the odd colouring of that line in Qt Creator, but surely it's not just a coincidence. (BTW I tried using highlighting on the relevant parts of the above, but it didn't display, so I removed it.)


    Added after 13 minutes:


    I closed Qt Creator and restarted it, and now the line colouring is OK. The compile error persists.
    Last edited by gib; 20th August 2019 at 02:04.

  9. #9
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Q_DECLARE_METATYPE problem

    What does your MainWindow.h file look like? That's the source of the error.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  10. #10
    Join Date
    Mar 2010
    Location
    Auckland, NZ
    Posts
    121
    Thanks
    9
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Q_DECLARE_METATYPE problem

    Quote Originally Posted by d_stranz View Post
    What does your MainWindow.h file look like? That's the source of the error.
    I want to either insert the code here or attach the file, but I don't see how to do either. At the moment the last icon in the row is "Add link to QtCentre Wiki article", and if I click "Go Advanced" it takes me to a page where I'm told to push the back button and reload, which just cancels my reply. I don't understand why I sometimes but not always see the "#" icon.

    Now when I try to post this I get an error "Your submission could not be processed because the token has expired. Please reload the window."

    Edit: After logging out and in again, I now see the "#" and the "Attachments: icon.

    mainwindow.h attached.

    Thanks
    Gib
    Attached Files Attached Files

  11. #11
    Join Date
    Mar 2010
    Location
    Auckland, NZ
    Posts
    121
    Thanks
    9
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: Q_DECLARE_METATYPE problem

    In answer to an old question on QtForum, raven-worx said "don't declare your mouse-handlers as slots". I had "void clickedGraph(MouseEvent *)" declared under "private slots:". I shifted it to "private:", and now the build completes without error.
    I have no idea why, but it seems that my problem is solved.

  12. #12
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Q_DECLARE_METATYPE problem

    I have no idea why, but it seems that my problem is solved.
    In a header file, "slots" is a magic keyword that the C++ compiler ignores, but which triggers the MOC compiler to create boilerplate code in the moc_*.cpp file to support the slots you have declared. Qt events are not declared as slots in their base classes (QObject or QWidget), but as ordinary C++ protected virtual methods. The Qt "Q*Event" classes are not registered with the Qt metatype system (ie., there's no Q_DECLARE_METATYPE for them) so trying to compile the MOC-generated code produces the error.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Q_DECLARE_METATYPE(T); error
    By SentaVera in forum Qt Programming
    Replies: 3
    Last Post: 2nd January 2014, 15:40
  2. Q_DECLARE_METATYPE() questions.
    By hickscorp in forum Qt Programming
    Replies: 1
    Last Post: 29th June 2010, 17:04
  3. Problem to declare a stl map - Q_DECLARE_METATYPE
    By Althor in forum Qt Programming
    Replies: 5
    Last Post: 9th December 2008, 10:41
  4. How to use Q_DECLARE_METATYPE
    By lni in forum Qt Programming
    Replies: 6
    Last Post: 21st July 2008, 18:13
  5. Q_DECLARE_METATYPE and qVariantCanConvert
    By manojmka in forum Qt Programming
    Replies: 1
    Last Post: 1st April 2008, 07:13

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.