Ответ 1
Вы должны удалить папку debug
своего приложения и запустить ее снова, чтобы исправить эту проблему.
Я унаследовал класс от QObject:
class Parent: public QObject
{
Q_OBJECT
QObject* cl;
public:
Parent(QObject *parent=0):QObject(parent) {
cl = NULL;
}
QObject* getCl() const {
return cl;
}
void setCl(QObject *obj) {
cl = obj;
}
};
Но когда я пишу:
Parent ev;
Я получаю следующую ошибку:
main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Parent::metaObject(void)const " ([email protected]@@[email protected]@XZ)
main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __thiscall Parent::qt_metacast(char const *)" ([email protected]@@[email protected])
main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __thiscall Parent::qt_metacall(enum QMetaObject::Call,int,void * *)" ([email protected]@@[email protected]@@[email protected])
Вы должны удалить папку debug
своего приложения и запустить ее снова, чтобы исправить эту проблему.
Если вы используете Visual Studio, удалите строку Q_OBJECT
из файла заголовка, сохраните файл, поместите Q_OBJECT
обратно в файл заголовка, сохраните файл снова. Это должно генерировать файл moc_*
, и он должен правильно строить и связывать.
В отличие от названия, Rebuild Project
не уничтожит все и не сработает. Если вы недавно добавили QObject
в свой класс, вам придется снова запустить qmake
, например.
Это потому, что по умолчанию qmake
запускается только при значительных изменениях в вашем решении, таких как добавление новых исходных файлов или изменение файла .pro
. Если вы редактируете существующий файл, он не знает, что ему нужно запустить qmake
. Однако для изменения QObject-ness класса определенно требуется запустить qmake
снова.
Если вы очень параноик, вы можете удалить папку Debug
или Release
. Это, безусловно, заставит Qt строить все с нуля.
Если ваши файлы moc создаются в проекте visual studio, попробуйте включить их в проект, если они не включены в проект, а затем перестроят.
Итак, проблема в том, что мне нужен компилятор Qt MOC для компиляции моего .h файла. Это необходимо для любых классов, которые расширяют QObject или один из его дочерних элементов. Исправление (для меня), щелкнув правой кнопкой мыши по файлу заголовка, выбрав "Свойства", и установив "Тип элемента" в "Ввод MOC Mt", затем нажмите "Скомпилировать" в заголовке, а затем добавив полученный файл moc_myfilename.cpp в мой проект.
У меня была такая же проблема в Visual Studio и решила ее, выполнив следующие шаги:
Затем в конфигурации Custom Build Tool:
установите "Командная строка" на:
"$ (QTDIR)\bin\moc.exe" "% (FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc _% (имя файла).cpp" "-fStdAfx.h" "-f../../../SRC/ FileName.h" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_NETWORK_LIB -DWIN32_LEAN_AND_MEAN -DDIS_VERSION = 7 -D_MATH_DEFINES_DEFINED "-I.\SFML_STATIC" "-I.\GeneratedFiles" "-I." "-I $(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)." "-I $(QTDIR)\include\QtCore" "-I $(QTDIR)\include\QtGui" "-I $(QTDIR)\include\QtNetwork"
установите "Выходы" на:
.\GeneratedFiles\$(ConfigurationName)\moc _% (имя файла).cpp
установите "Дополнительные зависимости" на:
$ (QTDIR)\Bin\moc.exe;% (FullPath)
Ваши точные значения могут отличаться. Они обычно применяются через плагин Qt.
Я использую CMake для управления проектами Qt, а новый Q_OBJECT необходимо добавить под вызовом QT4_WRAP_CPP. Это создаст moc _ *. Cxx для включения в проект и очистит нерешенные внешние.
В моем случае (используя QtAdd-in с VS2012 и Qt v4.8.4) ни одно из вышеперечисленных предложений не работало. По какой-то причине VS не смог сгенерировать надлежащие файлы moc (вывод сборки: не найдены соответствующие классы. Сгенерировано не сгенерировано). Когда я скомпилировал соответствующие заголовки вручную (установка qt moc в качестве компилятора и нажатие "Compile" ), он произвел пустой файл moc,
Что делалось для компиляции всех необходимых mocs из командной строки (moc -o moc_SomeClass.cpp SomeClass.h), а затем заменить неправильные в папке GeneratedFiles.
Это только обходной путь (а не удобный для большого проекта), чтобы проект был успешно выполнен, но на самом деле не объясняет странное поведение VS/QtAdd-in.
Используя QtAdd-in с VS2010, я понял, что файлы moc _ *. cpp были обновлены в папке GeneratedFiles/Debug, хотя я был в режиме release. Копирование файлов в папку Release работало для меня.
У меня была эта проблема с Visual Studio 2012, когда у меня было определение класса Q_OBJECT в моем файле cpp. Перемещение определения класса в файл заголовка разрешило проблему.
Похоже, должно быть возможно поддерживать класс Q_OBJECT в cpp файле, добавив файл cpp в moc, но я не пробовал это.
Я добавил файлы cpp/ui в свой проект вручную, но забыл добавить файл заголовка явно как файл заголовка. Теперь при компиляции я получил аналогичное сообщение об ошибке, как указано выше, и файлы moc _ *. Cpp не были сгенерированы в каталоге отладки (или выпуска) сборки. Это была не такая очевидная ошибка, qmake не жаловался, и кроме сообщения компоновщика у меня не было ошибок.
Итак, если кто-нибудь снова столкнется с той же проблемой (или сделает ту же ошибку копирования и pase): убедитесь, что файлы заголовков также добавлены в файл проекта
У меня была эта проблема с "частным классом". Qt использует эту модель, несмотря на свой код. Мне очень понравилось.
В принципе, у вас есть приватно объявленный класс в определении класса публичного заголовочного файла с указателем на экземпляр его как члена данных открытого класса. (Примечание. Возможно, вам станет легче объявить его как класс друга.)
Затем создайте приватную версию своего класса в файле cpp для общедоступного. НЕ создавайте файл заголовка для этого частного класса. Делайте все грязные работы с этим классом. Это скрывает всю реализацию вашего публичного класса, включая других частных членов.
Не объясняя, что далее, здесь пункт, относящийся к этой теме. Чтобы получить работу Q_OBJECT, мне нужно было добавить это в cpp:
#include "MyPublicClass.moc"
Макет cpp выглядит следующим образом:
Это случилось со мной в последнее время при переключении с MingW на MSVC. У меня был прототип класса/структуры, который был указан как класс, а MingW не возражал.
MSVC определенно видит разницу между class
и struct
при прототипировании.
Надеюсь, что однажды кто-то поможет кому-то другому.
В моем случае ничего из этого не было, но это была моя ошибка.
Я переопределил виртуальные функции в файле .h(объявил их), но никогда не определял их в .cpp:)
Я решил проблему, добавив ее в файл заголовка:
#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H
... // all the header file content.
#endif
Любой ответ работает для меня в среде VS 2013. В конечном итоге я решаю проблему, удалив файл .h/.cpp из проекта и добавив его обратно.
Я работаю в VS2015 со встроенным клиентом Perforce p4v. В моем случае Perforce попытался добавить файл moc в депо, когда я вернул эту операцию, Perforce удалил этот файл moc из проекта и удалил его. Файл был воссоздан после следующей компиляции, но он не был включен в проект, я должен добавить его вручную в "Сгенерированные файлы", когда я наконец понял, в чем проблема.