Форум: Форум C++Разное
Новые темы: 00
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум C++

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Qt и Visual Studio 2010. Как разбить проект на три файла?
 
 автор: alsav22   (22.04.2012 в 00:34)   письмо автору
 
 

VC 2010 Express и qt-win-opensource-4.8.1-vs2010.
Сначала : прописать папку c:\Qt\4.8.1\bin в Path (один раз).
Для каждого проекта:
Свойста проекта, Все конфигурации, C/C++, Общие, Дополнительные каталоги включаемых файлов, добавить:
C:\Qt\4.8.1\include;C:\Qt\4.8.1\include\QtCore;C:\Qt\4.8.1\include\QtGui;C:\Qt\4.8.1\include\ActiveQt
Свойста проекта, Все конфигурации, Компоновщик, Общие, Дополнительные каталоги библиотек, добавить:
C:\Qt\4.8.1\lib
Свойста проекта, Все конфигурации, Компоновщик -> Ввод -> Дополнительные зависимости, добавить:
qtmaind.lib;QtCore4.lib;QtGui4.lib;
Свойста проекта, Все конфигурации, События постороения, Событие перед постороением, Командная строка, добавить: moc -o main.moc main.cpp

Создал проект:
#include <QtGui>
#include <QtCore>

class MainWindow : public QMainWindow
{
    public:
    explicit MainWindow(QWidget *parent = 0);
};

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
          QLabel* label=new QLabel(this);
label->setText("Hello World!");
label->setAlignment(Qt::AlignCenter);
setCentralWidget(label);
}

 int main(int argc, char **argv)
 {
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
 }


Всё нормально работает. Если разделить на три файла: заголовочный, с объявлением класса, *.cpp с реализацией класса и *.cpp с функцией main, то компоновщик пишет о неразрешённых внешних символах.
Наверное, это связано с командной строкой, которая запускается перед постороением: moc -o main.moc main.cpp. В ней записан только одни файл: main.cpp. Как сделать, чтобы moc обрабатывал несколько файлов?
Сейчас написал и решил ещё раз проверить. Разделил, приведённый выше код, на три файла и всё нормально построилось. Начал вспоминать, почему перед этим не компоновалось.Вспомнил что я вставлял в объявление класса макрос Q_OBJECT. Если его вставить в приведённый выше код, то компоновщик сообщит о трёх неразрешённых внешних элементах. Если в конце кода написать #include "main.moc", то всё построится нормально. Как сделать, чтобы при трёх файлах и наличии макросов Qt всё нормально строилось?

  Ответить  
 
 автор: cheops   (22.04.2012 в 10:47)   письмо автору
 
   для: alsav22   (22.04.2012 в 00:34)
 

>компоновщик пишет о неразрешённых внешних символах.
Не разрешенные символы к чему относятся к Qt?

PS Вообще по уму нужно добавить правила в XML-файл построения проекта, сейчас, к сожалению, нет возможности по-экспериментировать.

Попробуйте для начала просто прописать строки
moc -o main.moc main.cpp

для каждого cpp-файла, объектный код для h-файлов не создается об них можно не заботиться на этапе линковки.

  Ответить  
 
 автор: alsav22   (22.04.2012 в 13:27)   письмо автору
 
   для: cheops   (22.04.2012 в 10:47)
 

Если сделать так:
файл mainwindow.h:
#include <QtGui>
#include <QtCore>
#include <QObject>

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
};


файл main.cpp:
#include "mainwindow.h"

int main(int argc, char **argv)
 {
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
 }


файл mainwindow.cpp:
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QLabel* label=new QLabel(this);
label->setText("Hello World!");
label->setAlignment(Qt::AlignCenter);
setCentralWidget(label);
}


то при построении:
1>------ Построение начато: проект: Qt5, Конфигурация: Debug Win32 ------
1>  main.cpp(0): Note: No relevant classes found. No output generated.
1>  main.cpp
1>  Создание кода...
1>  Компиляция...
1>  mainwindow.cpp
1>  Создание кода...
1>  LINK : не найден или не выполнена сборка D:\MY C++Projects\Qt5\Debug\Qt5.exe при последней инкрементной компоновке; выполняется полная компоновка
1>mainwindow.obj : error LNK2001: неразрешенный внешний символ ""publicvirtual struct QMetaObject const * __thiscall MainWindow::metaObject(void)const " (?metaObject@MainWindow@@UBEPBUQMetaObject@@XZ)"
1>mainwindow.obj : error LNK2001: неразрешенный внешний символ ""publicvirtual void * __thiscall MainWindow::qt_metacast(char const *)" (?qt_metacast@MainWindow@@UAEPAXPBD@Z)"
1>mainwindow.obj : error LNK2001: неразрешенный внешний символ ""publicvirtual int __thiscall MainWindow::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@MainWindow@@UAEHW4Call@QMetaObject@@HPAPAX@Z)"
1>D:\MY C++Projects\Qt5\Debug\Qt5.exe : fatal error LNK1120: 3 неразрешенных внешних элементов
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========


Если убрать Q_OBJECT, то всё нормально. То же самое выдаёт и в случае, если весь код поместить в один файл main.cpp, но это решается написанием в конце кода строки: #include "main.moc" . При трёх файлах это не помогает.

>Попробуйте для начала просто прописать строки
>
moc -o main.moc main.cpp

>для каждого cpp-файла ...

Как это должно выглядеть? Две строки:
-o main.moc main.cpp
-o main.moc mainwindow.cpp
? Или как-то по другому?

  Ответить  
 
 автор: cheops   (22.04.2012 в 22:11)   письмо автору
 
   для: alsav22   (22.04.2012 в 13:27)
 

Да, даже три строки, и с разными названиями
moc -o main.moc main.cpp
moc -o mainwindow.moc mainwindow.cpp
moc -o mainwindow.moc.h mainwindow.h
Вообще это нужно прописать на уровне проекта, но у меня сейчас нет возможности поэкспериментировать и дать вам точную инструкцию, как наладить проект. Если у вас терпения хватит, пока я вернусь из командировки, я думаю мы подберем более удобную конфигурацию для VS2010.

  Ответить  
 
 автор: alsav22   (22.04.2012 в 23:38)   письмо автору
 
   для: cheops   (22.04.2012 в 22:11)
 

Благодарю! Терпения у меня хватит. Пока поэкспериментирую с *.moc файлами. Идея понятна.

Поэкспериментировал. Результат такой. Для данного кода обработка moc имеет смысл только для файла mainwindow.h (предполагаю, что из-за наличия в нём Q_OBJECT). Файлы main.moc и mainwindow.moc пустые получаются. Если делать #include "mainwindow.moc.h" в файл main.cpp или в mainwindow.cpp, или в оба, то при построении:
1>------ Построение начато: проект: Qt5, Конфигурация: Debug Win32 ------
1>  main.cpp(0): Note: No relevant classes found. No output generated.
1>  mainwindow.cpp(16): Note: No relevant classes found. No output generated.
1>  mainwindow.cpp
1>d:\my c++projects\qt5\mainwindow.h(5): error C2011: MainWindow: переопределение типа "class"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(40): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(48): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(52): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(61): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(62): error C2270: metaObject: модификаторы недопустимы для функций, не являющихся членами
1>d:\my c++projects\qt5\mainwindow.moc.h(63): error C2227: выражение слева от "->metaObject" должно указывать на тип класса, структуры или объединения либо на универсальный тип
1>d:\my c++projects\qt5\mainwindow.moc.h(63): error C2227: выражение слева от "->metaObject" должно указывать на тип класса, структуры или объединения либо на универсальный тип
1>d:\my c++projects\qt5\mainwindow.moc.h(66): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(70): error C2355: this: может указываться только в нестатических членах-функциях
1>d:\my c++projects\qt5\mainwindow.moc.h(71): error C2352: QMainWindow::qt_metacast: недопустимый вызов нестатической функции-члена
1>          c:\qt\4.8.1\src\gui\widgets\qmainwindow.h(65): см. объявление "QMainWindow::qt_metacast"
1>d:\my c++projects\qt5\mainwindow.moc.h(74): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(76): error C2352: QMainWindow::qt_metacall: недопустимый вызов нестатической функции-члена
1>          c:\qt\4.8.1\src\gui\widgets\qmainwindow.h(65): см. объявление "QMainWindow::qt_metacall"
1>  main.cpp
1>d:\my c++projects\qt5\mainwindow.h(5): error C2011: MainWindow: переопределение типа "class"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(40): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(48): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(52): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(61): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(62): error C2270: metaObject: модификаторы недопустимы для функций, не являющихся членами
1>d:\my c++projects\qt5\mainwindow.moc.h(63): error C2227: выражение слева от "->metaObject" должно указывать на тип класса, структуры или объединения либо на универсальный тип
1>d:\my c++projects\qt5\mainwindow.moc.h(63): error C2227: выражение слева от "->metaObject" должно указывать на тип класса, структуры или объединения либо на универсальный тип
1>d:\my c++projects\qt5\mainwindow.moc.h(66): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(70): error C2355: this: может указываться только в нестатических членах-функциях
1>d:\my c++projects\qt5\mainwindow.moc.h(71): error C2352: QMainWindow::qt_metacast: недопустимый вызов нестатической функции-члена
1>          c:\qt\4.8.1\src\gui\widgets\qmainwindow.h(65): см. объявление "QMainWindow::qt_metacast"
1>d:\my c++projects\qt5\mainwindow.moc.h(74): error C2027: использование неопределенного типа "MainWindow"
1>          d:\my c++projects\qt5\mainwindow.h(5): см. объявление "MainWindow"
1>d:\my c++projects\qt5\mainwindow.moc.h(76): error C2352: QMainWindow::qt_metacall: недопустимый вызов нестатической функции-члена
1>          c:\qt\4.8.1\src\gui\widgets\qmainwindow.h(65): см. объявление "QMainWindow::qt_metacall"
1>  Создание кода...
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========

  Ответить  
 
 автор: alsav22   (23.04.2012 в 18:08)   письмо автору
 
   для: alsav22   (22.04.2012 в 23:38)
 

Получилось так. В свойствах проекта прописать всё так, как описано в первом посте, кроме последнего пункта для командной строки перед построением. Там прописать:
moc -o moc_mainwindow.h.cpp mainwindow.h

Добавить файл:moc_mainwindow.h.cpp в файлы исходного кода проекта.
После этого всё нормально строится и запускается.
Может быть, можно и как-нибудь лучше сделать, но тут опыта не хватает.

  Ответить  
 
 автор: daytery   (13.08.2012 в 15:07)   письмо автору
 
   для: alsav22   (23.04.2012 в 18:08)
 

Проблема решается следующими действиями.
файл mainwindow.h:

#ifndef QMAINWINDOW_H
#define QMAINWINDOW_H 
#include <QtGui>
#include <QtCore>
#include <QObject>

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
};
#endif


файл main.cpp:

#include "mainwindow.h"
int main(int argc, char **argv)
 {
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
 }


файл mainwindow.cpp:

#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QLabel* label=new QLabel(this);
label->setText("Hello World!");
label->setAlignment(Qt::AlignCenter);
setCentralWidget(label);
}
#include "mainwindow.moc"

Для командной строки прописываешь:

moc -o mainwindow.moc mainwindow.h

Компилируешь.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования